Die folgende Klasse definiert zwei Methoden, von denen beide intuitiv die gleiche Funktionalität haben. Jede Funktion wird mit zwei Listen vom Typ List<? super Integer>
und einem booleschen Wert aufgerufen, der angibt, welche dieser Listen einer lokalen Variablen zugewiesen werden soll.Warum mag der ternäre Operator keine generischen Typen mit beschränkten Platzhaltern?
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;
}
}
Nach javac 1.7.0_45
, chooseList1
ist gültig während chooseList2
nicht ist. Es klagt:
java: incompatible types
required: java.util.List<? super java.lang.Integer>
found: java.util.List<capture#1 of ? extends java.lang.Object>
Ich weiß, dass die Regeln für den Typ eines Ausdrucks zu finden, die ternäre Operator (… ? … : …
) sind ziemlich komplex enthält, aber soweit ich sie verstehe, wählt es die spezifischste Art, auf die sowohl Das zweite und dritte Argument können ohne explizite Umwandlung konvertiert werden. Hier sollte dies List<? super Integer> list1
sein, aber es ist nicht.
Ich würde gerne eine Erklärung sehen, warum dies nicht der Fall ist, vorzugsweise mit einer Referenz der Java-Sprache Spezifikation und eine intuitive Erklärung, was schief gehen könnte, wenn es nicht verhindert wurde.
@BrianRoach Ich glaube nicht, dass das ein genaues Duplikat ist, während es eng verwandt ist. Es handelt sich um den Bedingungsoperator, der auf abgeleitete Rückgabetypen aus generischen Methodenaufrufen angewendet wird, wobei dies auf generische Wildcard-Capture-Typen angewendet wird. –