Страницы

Поиск по вопросам

вторник, 9 октября 2018 г.

Различия между extend и super в Generics

Для примера такой код:
public void add(List list) { list.add(1D); // можно list.add(new Object()); // нельзя }
Почему так? Ведь здесь - - написано: "любой тип, являющийся супер-классом для Number". А работает всё наоборот: "любой тип - наследник Number". Что не так? Почему работает наоборот?


Ответ

Да, действительно подразумевает "любой тип, являющийся супер-классом для Number". Плюс сам Number
По этой причине вы можете передать в метод, например, List
Так как тип элементов в этом списке "что-то, являющееся суперклассом для Number", то можно добавлять в список элементы, тип которых является дочерним для Number. Например, Integer
public void add(List list) { list.add(1); }
Это позволительно, так как в список можно добавлять элементы, тип которых является дочерним для типа элементов списка. Как в случае с обычным List
List list = new ArrayList<>(); list.add(1);
Однако вы не можете добавить в список new Object(), потому что нет никаких гарантий того, что в списке можно хранить элементы типа Object: под ? может "скрываться" не только Object, но и, например, сам Number. В случае других классов (? super X), имеющих промежуточные классы между Object и самим X - ещё и любой промежуточный класс.
Так как истинный тип элементов списка неизвестен (?), но любой класс имеет в качестве суперкласса Object, то с полученным из списка элементом можно работать только как с Object. Даже с той единицей, которую только что туда сами и положили.

В случае подразумевается "любой тип, являющийся дочерним классом для Number". Плюс сам Number
В этом случае вы сможете передать в метод, например, List
Так как тип элементов "что-то, являющееся дочерним классом для Number", то вы ничего не сможете добавить в список (кроме, разве что, null), ибо неизвестно что именно там может храниться.
А вот с полученным из списка элементом вы сможете работать как с Number
public static void add2(List list) { int value = list.get(0).intValue(); }
Потому что какие бы там ни были элементы в списке, но они определённо из дочерних для Number классов, а, значит, могут работать как Number

Комментариев нет:

Отправить комментарий