Lambda expressions can be written in any context that has a target type. The contexts that have target types are:
- Variable declarations and assignments and array initializers, for which the target type is the type (or the array type) being assigned to;
- Return statements, for which the target type is the return type of the method;
- Method or constructor arguments, for which the target type is the type of the appropriate parameter. If the method or constructor is overloaded, the usual mechanisms of overload resolution are used before the lambda expression is matched to the target type. (After overload resolution, there may still be more than one matching method or constructor signature accepting different functional interfaces with identical functional types. In this case, the lambda expression must be cast to the type of one of these functional interfaces);
- Lambda expression bodies, for which the target type is the type expected for the body, which is derived in turn from the outer target type. Consider
Callable<Runnable> c =
() -> () -> { System.out.println("hi"); }
;
The outer target type here is
Callable<Runnable>
, which has the function typeRunnable call() throws Exception;
so the target type of the lambda body is the function type of
Runnable
, namely therun
method. This takes no arguments and returns no values, so matches the inner lambda above; - Ternary conditional expressions (
?:
), for which the target type for both arms is provided by the context. For example:Callable<Integer> c = flag ? (() -> 23) : (() -> 42);
- Cast expressions, which provide the target type explicitly. For example:
Object o = () -> { System.out.println("hi"); }; // Illegal: could be Runnable or Callable (amongst others) Object o = (Runnable) () -> { System.out.println("hi"); }; // Legal because disambiguated
The type expected by the context in which
the lambda is used; see this page.
This is a higher-order function; it takes no arguments and returns
a function that takes no arguments and returns no result.
Leave a Reply