Dlaczego leki generyczne Java nie mogą być tablicami?

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)

Daniel Gratzer
źródło
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”).

DepressedDaniel
źródło
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.

Kod zerowy
źródło