Преобразование ограниченного подстановочного знака в неограниченный подстановочный знак в универсальном типе является ошибкой (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;
Другие вопросы по тегам