I was curious why a lambda with a return type can not be casted to a Runnable
whereas a non void method reference can.
Runnable r1 = () -> 1; // not allowed
// error: incompatible types: bad return type in lambda expression
// int cannot be converted to void
Runnable r2 = ((Supplier)() -> 1)::get; // allowed
In order to match a lambda to a single method interface, also called a "functional interface", several conditions need to be met: The functional interface has to have exactly one unimplemented method, and that method (naturally) has to be abstract.
A lambda in Java essentially consists of three parts: a parenthesized set of parameters, an arrow, and then a body, which can either be a single expression or a block of Java code.
Using Lambda Expressions Lambda expressions can be stored in variables if the variable's type is an interface which has only one method. The lambda expression should have the same number of parameters and the same return type as that method.
A lambda expression body can't throw any exceptions that haven't specified in a functional interface. If the lambda expression can throw an exception then the "throws" clause of a functional interface must declare the same exception or one of its subtype.
The Runnable
interface defines the run
method with return type void. In a lambda expression that means that the part following the arrow ->
must be a statement. This is explained in JLS §15.27.3:
If the function type's result is void, the lambda body is either a statement expression (§14.8) or a void-compatible block.
The JLS $14.5 clearly defines the syntax of a statement. As explained above it must be an "ExpressionStatement" (§ 14.8). Looking there, you can find that a simple literal is not an adequate expression, but a method invocation is (even if it returns something).
This is not really a “special” rule for Lambdas. It has always been acceptable to use a non-void method in a statement context (in which case, the return value is thrown away), but not so with a simple expression. For instance “String.valueOf(true);” is a valid java statement, that may occupy a line by itself, whereas “true;” is not and may not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With