Dlaczego leki generyczne Java nie mogą być tablicami?


10

Dlaczego tak się ArrayList<Integer>[] arr=new ArrayList<Integer>[40];dzieje , gdy próbuję utworzyć tablicę ArrayLists: występuje błąd, a Java nie pozwala na to?

Czy istnieje powód związany z implementacją generycznych w Javie, generycznych w dowolnym języku lub czegoś arbitralnego?


Odpowiedzi:


20

Jest to jedna z głównych dziur w ogólnych wersjach Javy, tablice są kowariantne , co oznacza, że ​​tablica typu Foo[]jest podklasą Object[]i ParentOfFoo[]. Porównaj to z tym, List<Foo>co nie ma tego zachowania.

Było to ważne, gdy Java nie miała generycznych (aż do Java 5), ​​ponieważ w przeciwnym razie coś w rodzaju ogólnej funkcji sortowania było po prostu niemożliwe.

Ma jednak ten trudny problem, który polega na tym, że tablice lubią wiedzieć, jakiego typu są w środowisku wykonawczym . Jednak generics w Javie opiera się na usuwaniu typu. Te dwie rzeczy w ogóle nie pasują do siebie i do tego dochodzi nasz problem.

Długa i krótka to, w Javie 1, tablice kowariantne częściowo wypełniały dziurę, którą stworzył brak generyków. Jednak gdy próbowali poprawnie wypełnić tę dziurę, zgodność wsteczna oznaczała, że ​​tablice były prawie niemożliwe do wdrożenia.

W rzeczywistości facet, który faktycznie stworzył platformę generyczną, Martin Odersky, mówił o tym tutaj podczas wywiadu, dlaczego stworzył Scalę. (Całkiem fascynujące, jeśli w ogóle interesujesz się historią Scali)


3

Czy istnieje powód związany z implementacją generycznych w Javie, generycznych w dowolnym języku lub czegoś arbitralnego?

W rzeczywistości jest to nieco arbitralne.

Problem polega na tym, że umożliwia on otwór w systemie typów, ponieważ ArrayList<T>[]można go rzucić, Object[]a następnie można wstawić ArrayList<U>tablicę, gdzie U != T.

Projektanci Java postanowili zablokować tę dziurę tak chętnie, jak to możliwe, nie pozwalając new ArrayList<T>[N]wcale.

Jednak można go również podłączyć, nie zezwalając na upcasting tablic ogólnych (bez ostrzeżenia „niezaznaczonego”).


Ta odpowiedź jest niedoceniana. Bardzo prosty i nie używa żargonu na niejasnych warunkach. Dziękuję bardzo.
Tung Nguyen,

Być może zechcesz IntegerObject[]String[]
wyjaśnić,

-3

ponieważ tablica jest kowariantna, przy czym każdy typ jest podklasą obiektu, co powoduje błąd w czasie wykonywania z powodu wyjątku rzutowania. podczas gdy rodzajowy jest niezmienny, więc gdy buduje na typie, upewnij się, że jest bezpieczny, więc jeśli typ inny niż ten tworzy typ, to daje błąd kompilatora.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.