Эта строка не компилируется:
test(E1.class,E2.class);
Существует только один параметр типа E
и Java должны соответствовать выведенные типы аргументов точно. Он не может вывести Example
, потому что объекты Class<E1>
и Class<E2>
, а не Class<Example>
. Инвариантность Java-дженериков предотвращает это.
Вы можете обойти эту проблему путем введения верхней грани подстановочного по родовому параметру типа test
«s:
public static <E extends Example> void test(Class<? extends E>... es)
Это позволяет Java сделать вывод Example
для E
, удовлетворяя верхнюю границу подстановочного с E1
и E2
.
Вторая строка создает необработанный массив Class
es, минуя дженерики и генерируя предупреждение «unchecked call».
new Class[]{E1.class,E2.class}
Если вы должны были попытаться предоставить аргумент типа для Class
здесь, вы получите ошибку компиляции с любым полупутем разумного параметром типа:
// 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});
Удовлетворяя умозаключение с помощью подстановки здесь просто раскрывается реальная проблема здесь - создание общего массива.
// Generic array creation
test(new Class<? extends Example>[]{E1.class,E2.class});
Большое спасибо. Это никогда не пагубно относилось к моей программе, но я определенно почесывал ее на некоторое время. Я очень благодарен за разъяснение. – Squirvin