Linia ta nie kompiluje:
test(E1.class,E2.class);
Jest tylko jeden typ parametru E
i Java musi dopasować przypuszczalne typy argumentów dokładnie. Nie można wywnioskować, że są to: Example
, ponieważ obiektami są Class<E1>
i Class<E2>
, a nie Class<Example>
. Niezmienność generycznych Java zapobiega temu.
Można obejść ten problem poprzez wprowadzenie górnej granicy wieloznaczny w zakresie ogólnego parametru typu test
„s:
public static <E extends Example> void test(Class<? extends E>... es)
Pozwala Java wywnioskować Example
dla E
, poprzez spełnienie górna granica wieloznaczny z E1
i E2
.
Druga linia tworzy nieprzetworzoną tablicę z Class
es, omijając generyczne i generując ostrzeżenie "niezaznaczone połączenie".
new Class[]{E1.class,E2.class}
Jeśli było próbować dostarczyć typu argumentu Class
tutaj, dostaniemy błąd kompilatora z każdej połowie drogi rozsądnym parametru type:
// Needs Class<Example> but found Class<E1> and Class<E2>
test(new Class<Example>[]{E1.class,E2.class});
// Needs Class<E1> but found Class<E2>
test(new Class<E1>[]{E1.class,E2.class});
// Needs Class<E2> but found Class<E1>
test(new Class<E2>[]{E1.class,E2.class});
Zaspokojenie wnioskowania za pomocą wieloznacznych tutaj właśnie odkrywa prawdziwy problem - generyczne tworzenie macierzy.
// Generic array creation
test(new Class<? extends Example>[]{E1.class,E2.class});
Dziękuję bardzo. To nigdy nie było szkodliwe dla mojego programu, ale na pewno drapałem się po nim przez chwilę. Naprawdę doceniam wyjaśnienie. – Squirvin