Dlaczego operator trójskładnikowy nie lubi typów ogólnych z ograniczonymi symbolami wieloznacznymi?
Poniższa klasa definiuje dwie metody, obie intuicyjnie mają tę samą funkcjonalność. Każda funkcja jest wywoływana z dwoma listami typuList<? super Integer>
oraz wartość logiczna określająca, które z tych list powinny być przypisane do zmiennej lokalnej.
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;
}
}
Wedługjavac 1.7.0_45
, chooseList1
jest ważny, dopókichooseList2
nie jest. Narzeka:
java: incompatible types
required: java.util.List<? super java.lang.Integer>
found: java.util.List<capture#1 of ? extends java.lang.Object>
Wiem, że zasady wyszukiwania typu wyrażenia zawierającego operator trójskładnikowy (… ? … : …
) są dość złożone, ale o ile je rozumiem, wybiera najbardziej specyficzny typ, do którego można przekonwertować zarówno drugi, jak i trzeci argument bez wyraźnego rzutowania. Tutaj powinno byćList<? super Integer> list1
ale tak nie jest.
Chciałbym zobaczyć wyjaśnienie, dlaczego tak nie jest, najlepiej z odniesieniem doSpecyfikacja języka Java i intuicyjne wyjaśnienie, co może się nie udać, gdyby nie udało się temu zapobiec.