Как мне сделать родовые дженерики?
import java.util.LinkedList;
class GenericInseption{
public static void main(String[] args){
LinkedList<LinkedList<Dad>> listOfLists = new LinkedList<>();
LinkedList<Dad> list = new LinkedList<>();
listOfLists.add(list);
test(listOfLists);//error
}
private static void test(LinkedList<LinkedList<? extends Person>> listOfLists){
for(LinkedList<? extends Person> list : listOfLists){
for(Person person : list){
//peform operation on person objects
}
}
}
}
class Person{}
class Dad extends Person{}
ошибка
GenericInseption.java:7: error: method test in class GenericInseption cannot be applied to given types;
test(listOfLists);//error
^
required: LinkedList<LinkedList<? extends Person>>
found: LinkedList<LinkedList<Dad>>
reason: argument mismatch; LinkedList<LinkedList<Dad>> cannot be converted to LinkedList<LinkedList<? extends Person>>
1 error
но LinkedList
Как это должно работать?
1 ответ
Даже если LinkedList<Dad>
это подтип LinkedList<? extends Person>
, LinkedList<LinkedList<Dad>>
не является подтипом LinkedList<LinkedList<? extends Person>>
по той же причине, что List<Dog>
не является подтипом List<Animal>
Обобщения Java являются инвариантными. В этом случае они инвариантны на каждом уровне, а не только на ? extends Person
уровень, но на LinkedList<? extends Person>
уровень.
Добавьте еще один подстановочный знак перед LinkedList
на первом уровне дженериков в test
метод.
// vvvvvvvvv
private static void test(LinkedList<? extends LinkedList<? extends Person>> listOfLists){
Или, чтобы сделать его более широко применимым, используйте List
вместо LinkedList
:
private static void test(List<? extends List<? extends Person>> listOfLists){
for(List<? extends Person> list : listOfLists){