Определение класса
public interface ITest {
Long foo();
}
public class Test implements ITest{
@Override
public Long foo() {
return 0L;
}
}
Методы
public Map<Long, List<? extends ITest>> moo() {
List<Test> a = List.of(new Test());
Map<Long, List<? extends ITest>> b = Map.of(1L, a);
return b;
}
public Map<Long, List<? extends ITest>> koo() {
List<Test> a = List.of(new Test());
Map<Long, List<Test>> b = Map.of(1L, a);
return b;
}
public List<? extends ITest> too() {
List<Test> a = List.of(new Test());
return a;
}
Я получаю ошибку только в функции koo(). Почему это не работает? Класс List, обернутый классом Map, не поддерживает дженерики?
Ниже приведена ошибка, которую я получаю.
Несовместимые типы. Найдено: 'java.util.Map<java.lang.Long,java.util.List<Test>>', требуется: 'java.util.Map<java.lang.Long,java.util.List<? расширяет ITest>>'
Я думаю, что это должно работать правильно, но это не так.
В вашем методе koo не используйте List<Test>, а используйте List<? extends ITest>. Это не одно и то же, но вы по какой-то причине ожидаете, что они будут одинаковыми.
Спасибо за ответ. Но вот чего я не понимаю, так это too работает, а koo не работает.. В чём разница? Метод too также возвращает объект List<Test>, но тип возвращаемого значения — List<? extends ITest>.
Я решил это благодаря вам. Я оценил тебя!




Ваш метод too компилируется, потому что List<Test> является подтипом объявленного возвращаемого типа метода List<? extends ITest>. Явный ? extends в возвращаемом типе делает List<Test> подтипом.
Ваш метод koo не компилируется, поскольку, хотя List<Test> является подтипом List<? extends ITest>, Map<Long, List<Test>> не является подтипом Map<Long, List<? extends ITest>>. Вложение этой связи дженериков в другой универсальный тип не допускается, поскольку вы используете инвариантные дженерики.
Если вы удалили ? extends из возвращаемого типа too, то этот метод не скомпилируется, поскольку List<Test> не является подтипом List<ITest>.
Например, то, что необходимо для too, добавьте ? extends к возвращаемому типу для koo, чтобы это скомпилировалось. Тип Map<Long, List<Test>> является подтипом Map<Long, ? extends List<? extends ITest>>, поэтому к нему добавлен ? extends.
// vvvvvvvvv
public Map<Long, ? extends List<? extends ITest>> koo() {
List<Test>не то же самое, чтоList<? extends ITest>(что бы ни былоTest?) -- следовательно,Map<Long, List<Test>>нельзя использовать/возвратить какMap<Long, List<? extends ITest>>--Map.of()иList.of()творят чудеса, они определяют правильный тип возвращаемого значения (если возможно)