Java Bounded Generics: Type inference bug? (Method invocation, JLS 15.12.2.7)

user508633

For the following snippet of code:

import java.util.List;

public class Main {
    interface Interface1<T> {}
    interface Interface2<T> extends Interface1<T> {}
    static class Bound {}
    interface BoundedI1<T extends Bound> extends Interface1<T> {}
    interface BoundedI2<T extends Bound> extends Interface2<T> {}

    public static void main(String[] args) {
        test((List<BoundedI2<?>>) null);
        //test2((List<BoundedI2<?>>) null);
    }

    public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

    public static void test2(List<? extends Interface1<? extends Bound>> list) {}
}

The compiler is OK with the first call, but complains if I uncomment the second. Is this a bug in the type inference system, or can someone explain why the inference rules in the JLS fail here?

Tested on both 6u43 and 7u45 Oracle JDKs.

UPDATE: Seems like eclipsec accepts it just fine. Unfortunately I can't really change up our toolchain :P, but it is interesting to find differences in the compilers.

The error message, as printed by ideone (cool tool btw):

Main.java:12: error: method test2 in class Main cannot be applied to given types;
        test2((List<BoundedI2<?>>) null);
        ^
  required: List<? extends Interface1<? extends Bound>>
  found: List<BoundedI2<?>>
  reason: actual argument List<BoundedI2<?>> cannot be converted to List<? extends Interface1<? extends Bound>> by method invocation conversion

UPDATE 2: This compiles fine, which indicates that the compiler does think BoundedI2<?> is assignable to Interface1<? extends Bound>, which seems to more directly contradict the JLS:

public class Main {
    interface Interface1<T> {}
    interface Interface2<T> extends Interface1<T> {}
    static class Bound {}
    interface BoundedI1<T extends Bound> extends Interface1<T> {}
    interface BoundedI2<T extends Bound> extends Interface2<T> {}

    public static void main(String[] args) {
        test((List<BoundedI2<?>>) null);
        //test2((List<BoundedI2<?>>) null);
        test3((BoundedI2<?>) null);
    }

    public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

    public static void test2(List<? extends Interface1<? extends Bound>> list) {}
    public static void test3(Interface1<? extends Bound> instance) {}
}
Eric Nicolas

It looks like the command line compiler have some difficulties handling at the same time

  • the fact that BoundedI2 is generic on T which must be a "Bound"
  • the fact that Interface2 is extending Interface1

At least without instanciating BoundedI2 correctly. What is strange indeed is that Eclipse configured on the same JDK compiles it just fine... Note that Eclipse uses it's internal compiler in order to handle incremental recompulation while you type, so it does not invoke the JDK's compiler at all (see org/eclipse/jdt/internal/compiler package).

This modification makes it compile ok both in Eclipse and in the command line, by forcing BoundedI2 to be on a concrete type rather than on a type inference:

import java.util.List;

public class PerfTest {
    interface Interface1<T> {}
    interface Interface2<T> extends Interface1<T> {}
    static class Bound {}
    interface BoundedI1<T extends Bound> extends Interface1<T> {}
    interface BoundedI2<T extends Bound> extends Interface2<T> {}
    static class Actual extends Bound {}

    public static void main(String[] args) {
        test((List<BoundedI2<Actual>>) null);
        test2((List<BoundedI2<Actual>>) null);
    }

    public static void test(List<? extends Interface2<? extends Bound>> list) { test2(list); }

    public static void test2(List<? extends Interface1<? extends Bound>> list) {}
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Java/Scala Bounded Generics and type inference mismatch

From Dev

Why is javac compiling this code with bounded type generics on the return type of a method? Is it an invalid type inference?

From Dev

Java Generics bounded type doesn't apply to method parameters

From Dev

Java Generics bounded wild card usages before the return type of a method

From Dev

Why does Java generics type inference break in chained method calls?

From Dev

Java type inference with lower bounded types

From Dev

Java Generics, Type Inference, Inheritance?

From Dev

Java Generics: Returning Bounded Generic Type

From Dev

Java ternary operator influence on generics type inference

From Dev

Problems using generics and type inference in Java

From Dev

Java6, Guava, generics, type inference

From Dev

Problems using generics and type inference in Java

From Dev

Java generics: Bound mismatch: The type is not a valid substitute for the bounded parameter of the type

From Dev

bounded wildcards in java generics

From Dev

bounded wildcards in java generics

From Dev

Type inference with Generics in Swift

From Dev

What are the usage wildcard or Bounded type parameters in Java Generics?

From Dev

Confusion over Java generic method type inference

From Dev

Confusion over Java generic method type inference

From Dev

Java 8 type inference static method call

From Dev

Java Generics and Bounded parameters in subclasses

From Dev

Bounded type as method parameter?

From Dev

TypeScript generics: argument type inference

From Dev

Generics and type inference for a generic factory

From Dev

Swift Generics Type Inference Extensions

From Dev

Generics and type inference for a generic factory

From Dev

Upper bounded generics VS superclass as method parameters?

From Dev

Java language spec: "an invocation of Class" as return type of method in annotation type

From Dev

Java type inference: reference is ambiguous in Java 8, but not Java 7

Related Related

  1. 1

    Java/Scala Bounded Generics and type inference mismatch

  2. 2

    Why is javac compiling this code with bounded type generics on the return type of a method? Is it an invalid type inference?

  3. 3

    Java Generics bounded type doesn't apply to method parameters

  4. 4

    Java Generics bounded wild card usages before the return type of a method

  5. 5

    Why does Java generics type inference break in chained method calls?

  6. 6

    Java type inference with lower bounded types

  7. 7

    Java Generics, Type Inference, Inheritance?

  8. 8

    Java Generics: Returning Bounded Generic Type

  9. 9

    Java ternary operator influence on generics type inference

  10. 10

    Problems using generics and type inference in Java

  11. 11

    Java6, Guava, generics, type inference

  12. 12

    Problems using generics and type inference in Java

  13. 13

    Java generics: Bound mismatch: The type is not a valid substitute for the bounded parameter of the type

  14. 14

    bounded wildcards in java generics

  15. 15

    bounded wildcards in java generics

  16. 16

    Type inference with Generics in Swift

  17. 17

    What are the usage wildcard or Bounded type parameters in Java Generics?

  18. 18

    Confusion over Java generic method type inference

  19. 19

    Confusion over Java generic method type inference

  20. 20

    Java 8 type inference static method call

  21. 21

    Java Generics and Bounded parameters in subclasses

  22. 22

    Bounded type as method parameter?

  23. 23

    TypeScript generics: argument type inference

  24. 24

    Generics and type inference for a generic factory

  25. 25

    Swift Generics Type Inference Extensions

  26. 26

    Generics and type inference for a generic factory

  27. 27

    Upper bounded generics VS superclass as method parameters?

  28. 28

    Java language spec: "an invocation of Class" as return type of method in annotation type

  29. 29

    Java type inference: reference is ambiguous in Java 8, but not Java 7

HotTag

Archive