Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must throw statements be enclosed with a full code block in a lambda body? [duplicate]

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(); }); 
like image 654
Dragan Bozanovic Avatar asked Apr 09 '17 14:04

Dragan Bozanovic


People also ask

Can you throw any exception inside a lambda expression's body?

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.

How do you handle exception thrown by lambda expression?

A lambda expression cannot throw any checked exception until its corresponding functional interface declares a throws clause. An exception thrown by any lambda expression can be of the same type or sub-type of the exception declared in the throws clause of its functional interface.

Which exception is not supported by Lambda?

A lambda expression for this functional interface can't throw CheckedExceptions.

What is the return type of lambda expression?

The return type of a method in which lambda expression used in a return statement must be a functional interface.


2 Answers

AFAIK The jls says that the lambda body has to be:

expression or a block. Having it like this:

new Thread(() -> throw new RuntimeException()); 

is neither and the compiler somehow informs you about that.

Declaring it like this:

 new Thread(() -> {      throw new RuntimeException();  }); 

makes it a block. Here is the relevant part:

A block is a sequence of statements, local class declarations, and local variable declaration statements within braces.

like image 64
Eugene Avatar answered Sep 23 '22 13:09

Eugene


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.

throwStatement: 'throw' expression ';' ;  lambdaBody: expression | block;  expression: lambdaExpression | assignmentExpression;  block : '{' blockStatements? '}' ; 

Maybe it can be enhanced by including throwStatement into lambdaBody in the next jdk version if it is needed. Indeed, we need that as you mentioned above. for example:

lambdaBody: expression | block | throwStatement; 
like image 38
holi-java Avatar answered Sep 24 '22 13:09

holi-java