Java lambda только бросает выражение-стиль вместо выражения-стиля

В Java (используя Java 8 в настоящее время), я могу написать это, и все будет компилироваться хорошо и хорошо:

Supplier<Long> asd = () -> {
    throw new RuntimeException();
};

Но я не могу написать это:

Supplier<Long> asd = () -> throw new RuntimeException(); // This won't compile :(

Кто-нибудь знает, почему реализация Java не допускает такой стиль (выражение lambda) и только стиль lambda в стиле оператора/кода?

Я имею в виду, поскольку лямбда только бросает RuntimeException, почему JDK не может вывести выражение лямбда как:

new Supplier<Long>() {
    @Override
    public Long get() {
        throw new RuntimeException();
    }
};

Является ли это документированным где-то в спецификациях/документах? Это добавлено только в JDK> 8?

Ответ 1

Из спецификации языка JLS 15.27.2:

Тело лямбда является либо одним выражением, либо блоком (§14.2).

throw не является одним выражением (это утверждение); поэтому вы должны использовать его в блоке.

Ответ 2

То, что вы написали, является недопустимой лямбдой. Существует различие между выражением с скобками {} и без. См. Пример. Следующее означает, что возвращается 1L.

Supplier<Long> asd = () -> 1L;

что эквивалентно:

Supplier<Long> asd = () -> {
    return 1L;
}; 

Однако, когда вы пишете:

Supplier<Long> asd = () -> throw new RuntimeException();

Это будет переведено, что является недопустимой лямбдой:

Supplier<Long> asd = () -> {
     return throw new RuntimeException();                    // invalid expression in Java
};

В двух словах вы можете понять () → 1L как ярлык для { return 1L; } { return 1L; }.