Как мне сделать родовые дженерики?

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 является подтипом 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){
Другие вопросы по тегам