Java 8 представила 4 важных «формы функций» в пакете java.util.function
.
- Consumer -> принимает ссылку на метод (или лямбда-выражение), которая принимает один аргумент, но ничего не возвращает
- Поставщик -> принимает ссылку на метод (или лямбда-выражение), которая не принимает аргументов и возвращает объект.
- Функция -> принимает ссылку на метод (или лямбда-выражение), которая принимает один аргумент и возвращает объект.
- 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
, даже если назначенная ссылка на метод не принимает аргументов.