The basic syntax of a lambda expression is:
(parameters) -> expression
or
(parameters) -> {statements;}
In your first statement, throw new RuntimeException("test");
is a statement (more specifically, a throw Statement), so it should be surrounded by brackets:
new Thread(() -> {throw new RuntimeException("test")});
In the second statement, new RuntimeException("test")
is an expression, (more specifically, a Class Instance Creation Expression). That's why it works without the brackets and the semicolon.
================A little something additional====================
Here, the lambda expression () -> new RuntimeException("test")
works with the Runnable
interface whose return type is void
. Actually, it could also work with something returning an Exception
, e.g.:
@FunctionalInterface interface ExceptionSupplier{Exception supply();} //another functional interface that it works with!
ExceptionSupplier e = () -> new RuntimeException("test");
System.out.println(e.supply()); //prints "java.lang.RuntimeException: test"
In this case, the very same expression is evaluated as
ExceptionSupplier e = () -> {return new RuntimeException("Test");};
This is because the expression () -> new RuntimeException("test")
is both void-compatible and value-compatible (see here)
A block lambda body is void-compatible if every return statement in the block has the form return;.
A block lambda body is value-compatible if it cannot complete normally
(§14.21) and every return statement in the block has the form return
Expression;.
This answer has been inspired by both @AndyTurner and @Eran's answers.
Further complements are welcome.