List<List <? >> и List<List> являются несовместимыми типами в Java

Я не получил этот код для компиляции в любом случае:

List<List> a = new ArrayList();
List<List<?>> b = new ArrayList();

a = b; // incompatible types
b = a; // incompatible types

Кажется, что Java не считает List а также List<?> быть того же типа, когда дело доходит до дженериков.

Это почему? И есть ли какой-нибудь хороший выход?

контекст

Есть библиотечная функция со следующей подписью: public <T> Set<Class<? extends T>> getSubTypesOf(final Class<T> type), Это прекрасно работает для простых типов, передаваемых в качестве аргумента, но в случае обобщенных результатов результат не параметризуется с подстановочным знаком, вызывающим жалобу javac на необработанный тип. Я хотел бы распространить результат на остальную часть моего заявления как Set<Class<? extends GenericTypeHere<?>>> но простое приведение не работает, как я ожидаю.

РЕДАКТИРОВАТЬ: Решение

Спасибо за ответы, вот как я получаю это в итоге:

@SuppressWarnings({"rawtypes", "unchecked"})
private static Set<Class<? extends GenericTypeHere<?>>> factoryTypes() {
    return (Set) new Reflections("...").getSubTypesOf(GenericTypeHere.class);
}

2 ответа

Решение

Итак, это из-за тонкой семантической разницы.

List

Это сырой тип List, что приравнивается к T быть типом Object, Это то же самое, что сказать:

List<Object>

Теперь компилятор знает, что что бы ни случилось, это подкласс типа Object, И если вы делаете..

List myList = new ArrayList();
myList.add(new Object());

Это будет работать нормально! Это потому что Object то же самое, или это какой-то вывод типа.

List<?>

Это буквально список неизвестных ( Java Docs). Мы даже не знаем, что подкласс вещей здесь имеет тип Object, На самом деле, ? Тип - неизвестный тип, сам по себе. Это не имеет ничего общего с Object! Вот почему, когда вы пытаетесь и делаете..

List<?> myList = new ArrayList<?>();
myList.add(new Object());

Вы получаете ошибку времени компиляции!

    List<? extends List> a = new ArrayList();
    List<? extends List<?>> b = new ArrayList();
    a = b;

работает

Set<Class<? extends GenericTypeHere<?>>>

будет означать, Set<Class<YourClass extends AnotherClass<YourClass>>>как упомянуто в ответе подстановочного знака выше

Что мешает вам использовать

Set<Class<YourClass extends AnotherClass>> распространяться по всему вашему приложению?

Другие вопросы по тегам