Java 8 представила 4 важных «формы функций» в пакете java.util.function
.
- Потребитель -> принимает ссылку на метод (или лямбда-выражение), которая принимает один аргумент, но ничего не возвращает
- Поставщик -> принимает ссылку на метод (или лямбда-выражение), которая не принимает аргументов и возвращает объект.
- Функция -> принимает ссылку на метод (или лямбда-выражение), которая принимает один аргумент и возвращает объект.
- Predicate -> принимает ссылку на метод (или лямбда-выражение), которая принимает один аргумент и возвращает логическое значение.
Прочтите документацию по Java. для более подробной информации.
Чтобы ответить на ваш вопрос о том, почему первый работает, а второй выдает ошибку, прочитайте следующее:
Второе утверждение
consume(getHolded);
не работает, потому что тип аргумента getHolded
равен Function<Holder, String>
, тогда как метод consume
ожидает аргумент типа Consumer<Holder>
. Поскольку между Function
и Consumer
нет отношения родитель-потомок, требуется явное приведение, без которого компилятор правильно ошибается.
Первое утверждение
consume(Holder::getHolded);
работает, потому что метод getHolded
объявлен как public String getHolded()
, что означает, что он не принимает никаких аргументов и возвращает String
. Согласно новому правилу void compatibility, типы void выводятся как класс, содержащий указанный метод. Рассмотрим следующее утверждение:
Consumer<Holder> consumer = Holder::getHolded;
Это правильное утверждение, хотя метод getHolded
не принимает никаких аргументов. Это позволяет облегчить вывод типов пустот. Еще один пример - тот, который вы упомянули сами:
Function<Holder, String> getHolded = Holder::getHolded;
Это также правильное утверждение, если вы сказали, что объект функции getHolded
является Function
, который возвращает String
и принимает тип Holder
, даже если назначенная ссылка на метод не принимает никаких аргументов.
person
VHS
schedule
16.05.2018
consumer(getHolded::apply)
. - person Joshua Taylor   schedule 16.05.2018consumer(getHolded::apply)
будет соответствовать тому же правилу совместимости void, что и представленноеconsume(Holder::getHolded)
;) это правило упоминается @Eugene ниже - person Tomasz Bielaszewski   schedule 18.05.2018