Следующий класс определяет два метода, оба из которых интуитивно имеют одинаковую функциональность. Каждая функция вызывается с двумя списками типа List<? super Integer>
и логическим значением, которое указывает, какой из этих списков следует назначить локальной переменной.
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;
}
}
Согласно javac 1.7.0_45
, chooseList1
действует, а chooseList2
- нет. Он жалуется:
java: incompatible types
required: java.util.List<? super java.lang.Integer>
found: java.util.List<capture#1 of ? extends java.lang.Object>
Я знаю, что правила поиска типа выражения, содержащего тернарный оператор (… ? … : …
), довольно сложны, но, насколько я понимаю, он выбирает наиболее специфический тип, к которому относятся как второй, так и третий аргументы могут быть преобразованы без явного приведения. Здесь это должно быть List<? super Integer> list1
, но это не так.
Я хотел бы получить объяснение, почему это не так, желательно со ссылкой на спецификацию языка Java и интуитивное объяснение того, что может пойти не так, если это не было предотвращено.