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>>
распространяться по всему вашему приложению?