In Java (using Java 8 currently), I can write this and all will compile nice and well:
Supplier<Long> asd = () -> {
    throw new RuntimeException();
};
Yet, I cannot write this:
Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(
Does anyone know why Java's implementation does not allow such style (expression lambda) and only the statement/code-block style lambda?
I mean, since the lambda is only throwing the RuntimeException, why isn't the JDK able to infer the lambda expression as:
new Supplier<Long>() {
    @Override
    public Long get() {
        throw new RuntimeException();
    }
};
Is this documented somewhere in the specs/docs? Is this added only in JDK > 8?
From the language spec JLS 15.27.2:
A lambda body is either a single expression or a block (§14.2).
throw is not a single expression (it's a statement); so you have to use it in a block.
What you wrote is an invalid lambda. There is a difference between the expression with the brackets {} and without. See the example. The following means that 1L is returned.
Supplier<Long> asd = () -> 1L;
which is equivalent to:
Supplier<Long> asd = () -> {
    return 1L;
}; 
However, when you write:
Supplier<Long> asd = () -> throw new RuntimeException();
It would be translated following which is an invalid lambda:
Supplier<Long> asd = () -> {
     return throw new RuntimeException();                    // invalid expression in Java
};
In a nutshell, you can understand () -> 1L as a shortcut for { return 1L; }.
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