Список вызовов с другим типом вызовет ошибку. Правильный ли мой вывод?
Да; например, вы не можете пропустить List<String>
. Обычно цель вашего второго метода addList неверна. Правильная подпись такова:
public <T> List<T> addList(T t1, T t2, List<? extends T> list)
обратите внимание на синтаксис ? extends
. Если все, что вы делаете, это читаете из списка, то нет причин не добавлять это. Список некоторого определенного подтипа T гарантированно содержит Ts. Причина в том, что есть разница: что, если вы хотите ADD к этому списку? Допустим, T равен Number
, и вы передаете список Integer
. Двойной номер. С List<T> list
вы можете вызвать list.add(5.0)
, и он скомпилируется и запустится, поместив двойные числа в ваш список целых чисел. При List<? extends T>
вызов add всегда является ошибкой компилятора (если вы не попытаетесь добавить null
, что сработает). Для чтения вы получаете T
, независимо от того, звоните ли вы get
на List<? extends T>
или List<T>
, это не имеет значения.
1) Строка 28, когда передается String и class,
Нет, вы передаете экземпляр типа String и экземпляр типа GenericTest. String - это такой же класс, как и GenericTest. Строка не особенная. Это точно такой же сценарий, как ваш вызов в строке 21: вы передаете 2 выражения; один тип объекта X, а другой тип объекта Y. Следовательно, T
определяется как наиболее определенный общий тип (возможно, так называемый тип lub: набор типов) между двумя переданными экземплярами. В случае строк 21, Integer
и String
наиболее конкретный общий тип - это просто Object
(если быть техническим, то это тип lub Object & Serializable
, но здесь это в основном не имеет значения). В строке 28 это наиболее специфичный общий тип между String
и GenericTest
, который по-прежнему Object
, без разницы.
2) Строка 30, когда пройдены два разных класса,
см. Выше; точно такая же ситуация. Наиболее конкретный тип общего доступа между GenericTest
и GenericMethod
- Object
.
3) Строка 34, когда List, объявленный без типа, передается в качестве аргумента.
Выражение lst
в строке 34 имеет тип «raw» ArrayList
. когда вы используете необработанные типы, происходят две вещи: [1] компилятор предупредит вас о том, что вы используете необработанные типы, и [2] в значительной степени все универсальные тесты и проверки отключены для любых вызовов, которые включают любые необработанные типы, поэтому компилятор просто допустит это.
Помните, что дженерики - это плод воображения компилятора. Их цель - чтобы компилятор сказал вам, что ваш код не работает. Вот и все.