Ответ D, public static <T> List <? extends T> backwards(List <T> input)
, возвращает список, который может содержать тип T
или любой из его подклассов. Так как он может содержать T
, он может содержать любой элемент на входе и является «правильным» в этом смысле.
Ответ E, public static <T> List <? super T> backwards(List <T> input)
, аналогичен, но возвращает список, который может содержать T
или любой суперкласс. Поскольку он также может содержать элементы ввода, он также «правильный».
Выбор одной из этих альтернатив повлияет на то, что пользователь может ожидать от полученного списка.
С выходом List<? extends T>
можно перебирать список и назначать каждому элементу переменную типа T
, но ни один элемент, даже типа T
, не может быть безопасно добавлен в List
. (Кто-то может ссылаться на этот список как List<SubT>
и получит ClassCastException
при попытке получить T
как SubT
.)
С выходом List<? super T>
можно безопасно добавлять элементы в List
, если они имеют тип T
. Однако элемент из списка можно безопасно назначить только переменной типа Object
. (Кто-то может ссылаться на этот список как List<Object>
и добавлять экземпляры Object
или другие суперклассы T
).
С помощью List<T>
можно безопасно назначить элементы списка переменной типа T
и добавить элементы типа T
в список (при условии, что это модифицируемая List
реализация).