Целевой тип в лямбда-выражениях
У меня возникла небольшая путаница касательно понятия "целевой тип" в контексте лямбда-выражений.
Одно из определений: "Функциональный интерфейс , для которого было вызвано лямбда-выражение, называется целевым типом лямбда-выражения".
Другое: "Целевым типом лямбда-выражения называется тип контекста, в котором это выражение встречается, – например, тип локальной переменной, которой оно присваивается, или тип параметра метода, вместо которого оно передается."
Как я понимаю, во-втором определении, имеется в виду ссылка на функциональный интерфейс, к которой может быть присвоена лямбда-выражение. И вроде все сходится, но когда дело касается обобщений, то пишут следующее:
"При объявлении ссылки на функциональный интерфейс IValue< T > в аргументе типа нужно указать целевой тип лямбда-выражения".
В общем, что такое целевой тип в лямбда-выражениях?
Ответы (1 шт):
Наверно, проще будет объяснить на примерах:
- Первое определение: Функциональный интерфейс, для которого было вызвано лямбда-выражение, называется целевым типом лямбда-выражения
Runnable r = () -> System.out.println("Hi"); // целевой тип: Runnable
IntUnaryOperator sign = Integer::signum; // целевой тип: IntUnaryOperator
IntBinaryOperator add = (a, b) -> a + b; // целевой тип: IntBinaryOperator; a и b - int
Целевые типы -- интерфейсы, которые извлекаются из контекста.
- Второе определение: При объявлении ссылки на функциональный интерфейс
IValue<T>в аргументе типа нужно указать целевой тип лямбда-выражения
Данное определение приводится например здесь: Лямбда-выражения для обобщенных функциональных интерфейсов. Примеры (англ. версия: Lambda expressions for generic functional interfaces. Examples)
interface IValue<T> {
T getValue();
}
Однако, здесь же сначала указывается: В этом случае [если функциональный интерфейс является обобщённым] целевой тип лямбда-выражения определяется на основании типа, указанного в ссылке на этот функциональный интерфейс.
Таким образом, целевым типом лямбда-выражения следует считать конкретизированный интерфейс (когда в ссылке указан конкретный класс), т.е. в приведённом примере таким типом будет IValue<Float>, тогда как Float является аргументом типа (type argument).
IValue<Float> refIValue = () -> 3.1415f; // Целевой тип IValue<Float>