Страницы

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

суббота, 14 декабря 2019 г.

Для чего нужны <? extends> и <? super> как параметры метода

#java #generics #lambda #java_stream


Есть функция:

 Stream map(Function mapper);


Она производит операции над элементами Stream и возвращает Stream с результирующими
элементами. На вход мы подаем реализацию функционального интерфейса, то есть метода: 

R apply(T t);


Я это и делаю:

.map(User::getName)


То есть, если я правильно понимаю, вместо T "подставляется" тип User, вместо R тип
String. Тогда объясните , для чего вообще нужно super и extends в параметрах? 

Я понимаю, что super T означает: "T или любой его суперкласс", extends R означает
"R или любой его подкласс"?

В чем преимущество T по сравнению с super T, где это можно использовать? С обычным
методом все понятно (можем передать экземпляр любого суперкласса как параметр), а вот
с параметром типа функционального интерфейса не очень. 

Мы ведь просто передаем реализацию с конкретными T(User) и R(String), где нам тогда
могут пригодится подклассы и суперклассы? 
    


Ответы

Ответ 1



Java generics построены на идеи PECS (production - extends; consumer - super), т.е. производитель определяет верхние границы, а потребитель определяет нижние границы. Потом в Function где T - входные данные, а R - выходные данные. Его часто называют отображением, так как входные данные "отображаются" в выходные. Рассмотрим пример: Function fun = (str) -> Integer.parseInt(str); System.out.println(fun.apply("234")); Здесь входной должна быть строчкой, а в выходе мы получим Integer. Получается в вашем варианте входной был User, а выходе мы должны получить имя юзера.

Ответ 2



Как раз таки наоборот, преимущество типа ? super T по сравнению с T состоит в том, что в первом случае на вход функции можно посылать объекты разных типов, которые либо T либо являются суперкласом T. То есть мы не можем сказать, что тип параметра T. А также, мы не можем посылать объекты наследники T, в качестве параметра функции. Во втором случае тип T определен однозначно по иерархии, несмотря на то, что он является обобщенным типом, не принимаются наследники T и он не является наследником T.

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

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