Преобразование ограниченного подстановочного знака в неограниченный подстановочный знак в универсальном типе является ошибкой (X<Y <? Расширяет T >> до X<Y <? >>
Рассмотрим этот пример:
private <T> void m(Class<? extends T> k, Set<Class<? extends T>> sk) {
Class<?> ku = k;
Set<Class<?>> sku = sk; // <-- Type mismatch: cannot convert from
// Set<Class<? extends T>> to Set<Class<?>>
}
Другими словами, я могу назначить Class<? extends T>
к Class<?>
для некоторого произвольного T
но не Set<Class<? extends T>>
к Set<Class<?>>
,
Вероятно, это как-то связано с некоторым ограничением ковариации / контравариантности, но что?
Я мог бы представить актерский состав: Class.class::cast
сделал бы это. Но есть ли способ подчинить компилятор моей воле с помощью тонкого type-fu, вместо того, чтобы ударить его по голове при помощи приведения?
1 ответ
Даже если Class<? extends T>
это Class<?>
, Set<Class<? extends T>>
это не Set<Class<?>>
по той же причине, что хотя Dog
является Animal
, List<Dog>
это не List<Animal>
, Вот, ? extends T
имеет ту же роль, что и Dog
, а также ?
имеет ту же роль, что и Animal
,
Вам понадобится ? extends
перед Class
чтобы это правильно скомпилировать.
Set<? extends Class<?>> sku = sk;