Ответ 1
Из спецификации языка JLS 15.27.2:
Тело лямбда является либо одним выражением, либо блоком (§14.2).
throw
не является одним выражением (это утверждение); поэтому вы должны использовать его в блоке.
В 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?
Из спецификации языка JLS 15.27.2:
Тело лямбда является либо одним выражением, либо блоком (§14.2).
throw
не является одним выражением (это утверждение); поэтому вы должны использовать его в блоке.
То, что вы написали, является недопустимой лямбдой. Существует различие между выражением с скобками {}
и без. См. Пример. Следующее означает, что возвращается 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; }
.