вызова метода с List<String>
в качестве аргумента как вызов следующий метод:
public static List<? super String> m(List<String> list) { ... }
Рассмотрим следующий исходный код:
List<String> list = new ArrayList<>();
List<? super String> result = m(list);
Это вызывает вышеупомянутый метод и сохраняет возвращенную значение в переменную result
- которая вводится точно с типом возвращаемого метода.
Вопрос: какие переменные - или лучше какие типы - можете ли вы присвоить эту переменную? Поэтому мы говорим о совместимости присваивания.
Рассмотрим эти задания:
List<String> result1 = result; // compiler error: type mismatch (not assignable)
List<Object> result2 = result; // compiler error: type mismatch (not assignable)
List result3 = result; // ok
List<?> result4 = result; // ok
List<? super String> result5 = result; // ok
List<? extends Object> result6 = result; // ok
Чтобы понять природу этой ошибки, вы должны знать, что генерики инвариантную. Это означает, что тип List<String>
не является подтипом List<Object>
- хотя типы String
и Object
имеют такую иерархию подтипов.
Итак, что мы пытаемся здесь:
- Назначение
List<? super String>
к List<String>
=> не удается, не подтипов
- не Присвоить
List<? super String>
к List<Object>
=> не удается, не подтипов
- Присвоить a
List<? super String>
до List
=> успешно, потому что использование необработанных типов отказывается от проверки типа вообще
- Присвойте
List<? super String>
List<?>
=> Преуспевает, потому что List<?>
является супертипом всех List<...>
- Назначьте
List<? super String>
к List<? super String>
=> преуспевает, потому что ... ну ...
- Присвоить
List<? super String>
к List<? ectends Object>
=> преуспевает, потому что List<? ectends Object>
является по существу то же самое, что и List<?>
.
Обратите внимание, что попытка назначить List<? super String>
к List<? super CharSequence>
или List<? extends CharSequence>
также потерпит неудачу. Они не находятся в иерархии подтипов.
Почему это так? Компилятор не может гарантировать, что фактический список был создан с типом, который соответствует ограничению ? super/extends CharSequence
.
Я спрашиваю, почему мой «результат» не может быть «списком
Почему вы используете подстановочный знак в качестве возвращаемого типа? Это довольно странная вещь ... – fge
@fge Это метод библиотеки, а не мой. – bladekp