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

153
10 августа 2018, 19:50

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

<R> Stream<R> map(Function<? super T, ? extends R> 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), где нам тогда могут пригодится подклассы и суперклассы?

Answer 1

Java generics построены на идеи PECS (production - extends; consumer - super), т.е. производитель определяет верхние границы, а потребитель определяет нижние границы.

Потом в Function где T - входные данные, а R - выходные данные. Его часто называют отображением, так как входные данные "отображаются" в выходные. Рассмотрим пример:

Function<String, Integer> fun = (str) ->
            Integer.parseInt(str);
    System.out.println(fun.apply("234"));

Здесь входной должна быть строчкой, а в выходе мы получим Integer. Получается в вашем варианте входной был User, а выходе мы должны получить имя юзера.

Answer 2

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

READ ALSO
Не подключается шрифт

Не подключается шрифт

Подключаю шрифт, в папке с проектом имеет такой вид и на сайте он работает

167
помогите с проммисом

помогите с проммисом

код функции qw менять нельзя можно менять только колбек

165
Как сделать, чтобы ячейки одного цвета не встречались вместе слева направо?

Как сделать, чтобы ячейки одного цвета не встречались вместе слева направо?

Надо сделать так, чтобы ячейки одного цвета не встречались вместе слева направо

174
Bundle не работает как статический сайт

Bundle не работает как статический сайт

При запуске React приложения через открытие indexhtml - белый экран

148