The following class defines two methods, both of which intuitively have the same functionality. Each function is called with two lists of type List<? super Integer>
and a boolean value which specifies which of those lists should be assigned to a local variable.
import java.util.List;
class Example {
void chooseList1(boolean choice, List<? super Integer> list1, List<? super Integer> list2) {
List<? super Integer> list;
if (choice)
list = list1;
else
list = list2;
}
void chooseList2(boolean choice, List<? super Integer> list1, List<? super Integer> list2) {
List<? super Integer> list = choice ? list1 : list2;
}
}
According to javac 1.7.0_45
, chooseList1
is valid while chooseList2
is not. It complains:
java: incompatible types
required: java.util.List<? super java.lang.Integer>
found: java.util.List<capture#1 of ? extends java.lang.Object>
I know that the rules for finding the type of an expression containing the ternary operator (… ? … : …
) are pretty complex, but as far as I understand them, it chooses the most specific type to which both the second and third arguments can be converted without an explicit cast. Here, this should be List<? super Integer> list1
but it isn't.
I'd like to see an explanation of why this isn't the case, preferably with a reference of the Java Language Specification and an intuitive explanation of what could go wrong if it wasn't prevented.