I ran into an issue where the allowed syntax of a Lambda has changed between versions 1.8.0_05 and 1.8.0_20 (beta) of the java compiler.
Example:
p
In the Java programming language, a method invocation expression is an Expression Statement, a construct which can appear at both places, where an expression is required or where a statement is required.
Therefore you can use the simplified expression form param -> expression
for the use case e -> System.out.println("hi")
even if the method returns void
. Since the function signature expected here is <T extends Event> T -> void
, your lambda expression containing a single invocation of a void
method is valid for this context.
Things change when you are trying to use the Expression Statement in a different context where an expression is required. Compare JLS §15.1:
An expression denotes nothing if and only if it is a method invocation (§15.12) that invokes a method that does not return a value, that is, a method declared void (§8.4). Such an expression can be used only as an expression statement (§14.8), because every other context in which an expression can appear requires the expression to denote something.
Applying this rule formally, even simply putting braces around it like in (System.out.println("hi"))
is invalid as this is a compound expression trying to use the method invocation of a method declared void
in a context where a “real expression” (returning a value) is required.
And so the lambda expression using the invalid expression as in mi.setOnAction(e -> (System.out.println("hi")));
can’t be valid either. The message is a bit misleading. It seems that the compiler focuses on the fact that an expression of the form ( whatever )
, is a non-statement expression and therefore can’t be valid in a void
context. However, reporting the initial error of putting a void
method invocation in round braces would be more useful.
The rule that you can’t put ( … )
around a void
method invocation didn’t change, so the error was the older compiler accepting this syntax which seems to have been fixed now.