If there is a single statement in a lambda function, we can omit defining the full code block for it:
new Thread(() -> System.out.println());
Why is that not the case for statements that throw exceptions? This yields a compilation error stating '{' expected
:
new Thread(() -> throw new RuntimeException());
Of course, enclosing the lambda body in a code block works:
new Thread(() -> {
throw new RuntimeException();
});
A
throw
statement is, well, a statement and not an expression so it must be placed within braces. According to this article, the Java Expert Group had an informal survey on the syntax of lambdas at the time, and there were four options:#(arglist)(expr) and #(arglist){statements}
{ args -> statements }
(similar to Scala and Groovy)#{ args -> statements}
(args) -> { statements }
Ultimately, the choice was to adopt a syntax similar to that of C# according to this thread, which also looks closest to the last option above as far as I can see. In C#, there is a distinction between expression lambdas and statement lambdas:
Expression lambda (C#):
Statement lambda (C#):
The syntax is explained in this MSDN documentation page.
And the rationale for choosing this syntax over the other options is mentioned in the previous thread:
In Java8, the grammar of a lambda body only accepts an expression or a block. Whereas throwing an exception is a statement, not an expression.
Maybe it can be enhanced by including
throwStatement
intolambdaBody
in the next jdk version if it is needed. Indeed, we need that as you mentioned above. for example:AFAIK The jls says that the lambda body has to be:
expression or a block. Having it like this:
is neither and the compiler somehow informs you about that.
Declaring it like this:
makes it a block. Here is the relevant part: