2014-09-05 12 views
5

Natknąłem się na niezgodne typy błędów, których przyczyny nie rozumiem.Typy niekompatybilne z generics

Dlaczego ten fragment kodu jest nieprawidłowy?

List<List<String>> a = new ArrayList<>(); 
List b = a; // is ok 
List<List> c = a; // incompatible types 

Odpowiedz

7

Jest to opisane here. Zgodność nadprzyrodzonych działa tylko na "zewnętrznym" poziomie, ale nie "wewnątrz" w parametrach typu. To nie jest intuicyjne, ale tak to działa ... Ponadto, List jest typu surowego i zachowuje się nieco inaczej niż List<Object> - który jest opisany here.

3
List<List> 

jest niejawnie

List<List<Object>>

który nie jest rodzicem

List<List<String>> 

powód dlaczego to się uda w pierwszym przypadku jest ze względu na typ wnioskowania. Kompilator będzie zasadniczo sprawdzić, jaki typ jest potrzebny do wyrażania sensu i będzie generować

List<List<String>> a = b; 

W drugim przypadku będzie to domyślnie

List<List<Object>> a = b // which does not compile 
+0

Mam to, ale dlaczego druga linia nie daje błędu czasu kompilacji, ponieważ może to prowadzić do tych samych błędów w czasie wykonywania co trzeci wiersz? –

+0

To jest właśnie powód, dla którego powinieneś preferować generics nad surowymi typami. Ogólny kod gwarantuje bezpieczeństwo typu w tym przypadku, surowy kod nie. – Seb

3

Pisanie

List b = a; 

Nie obejmuje leków generycznych. Definiuje surowy typ listy o nazwie b, który może przyjmować dowolny obiekt jako jego element.

Nie porównuj go z

List<List> c = a; 

ponieważ wiąże rodzajowych i dlatego kompilator wymusi sprawdzenie zgodności typu tutaj.

+0

Tak, ale jeśli dalej w kodzie, zadzwonimy do b.add (new Object()); spowoduje błąd runtime, ponieważ w zasadzie wykonamy a.add (new Object()); Moje pytanie brzmi teraz: dlaczego trzecia linia zapobiega przypadkowym błędom, dając błędy w czasie kompilacji, podczas gdy druga nie oznacza, że ​​ –

+0

Ten błąd środowiska wykonawczego nie jest związany z naszą dyskusją dotyczącą sprawdzania zgodności typów. –

+0

Myślę, że na swój komentarz już udzielono odpowiedzi. –

2

Krótka odpowiedź: ponieważ twoja lista c zawiera listę wszystkich rodzajów obiektów. Na przykład można również dodać obiekty Integer.
I lista a może zawierać tylko obiekty String.

Powiązane problemy