The compiler infers type C for a parameter of type T in all three cases.
This is the most specific type that is suitable for restrictions.
The [T] inference algorithm tries to find the most specific type that works with all arguments.
For the first two statements
A a = testMe(listB, listC); B b = testMe(listB, listC);
Both B and C match because a List<B> matches List<? super B> List<? super B> and List<C> matches List<? extends B> List<? extends B> , and List<B> corresponds to List<? super C> List<? super C> and List<C> matches List<? extends C> List<? extends C> . The compiler selects the most suitable type that matches, C
You can force this to compile with an explicit type parameter to force the compiler to resolve it to B :
A a = Super.<B>testMe(listB, listC); B b = Super.<B>testMe(listB, listC);
The third line matches only C , so this compiler chooses for T
C c = testMe(listB, listC);
This is because the assigned variable is of type C , and B cannot be assigned to C
rgettman
source share