为什么 Consumer 或 Supplier 参数需要 {} 用于多个注释
Why Consumer or Supplier argument needs {} for multiple annotations
假设有一个 Optional
optString。现在,如果我按如下方式使用它:
optString.ifPresent({
//some statements
}, () -> throw new Exception());`, it fails to compile.
为什么我必须将 throw new Exception()
包裹在大括号 {}
.
内
为什么我不能简单地做 () -> throw new Exception
。
为什么编译器将 throw
和 new
视为应该在块中的某些状态?
在 IntelliJ 中它因编译错误而失败:expected ) expected { expected;
和 Unexpected token
一个完整的例子:
class OptionalTest {
Optional<String> testString() {
return Optional.empty();
}
void getString() {
var optStr = testString();
optStr.ifPresentOrElse(s -> {
}, () -> throw new RuntimeException());
}
}
您不能像以前那样在 lambda 表达式中简单地 throw
,因为 lambda 主体是单个表达式或块。 throw
是一个语句。
您必须将抛出异常包装到块中:
optStr.ifPresentOrElse(
str -> /*do something*/,
() -> { throw new RuntimeException(); });
还值得一提的是Optional#orElseThrow
,它被设计成实际抛出异常。传递给 Supplier
的唯一参数是实例化异常的方式,如果 Optional
为空,该方法将接受它并抛出而不是你。
optStr.orElseThrow(() -> new RuntimeException());
假设有一个 Optional
optString。现在,如果我按如下方式使用它:
optString.ifPresent({
//some statements
}, () -> throw new Exception());`, it fails to compile.
为什么我必须将 throw new Exception()
包裹在大括号 {}
.
为什么我不能简单地做 () -> throw new Exception
。
为什么编译器将 throw
和 new
视为应该在块中的某些状态?
在 IntelliJ 中它因编译错误而失败:expected ) expected { expected;
和 Unexpected token
一个完整的例子:
class OptionalTest {
Optional<String> testString() {
return Optional.empty();
}
void getString() {
var optStr = testString();
optStr.ifPresentOrElse(s -> {
}, () -> throw new RuntimeException());
}
}
您不能像以前那样在 lambda 表达式中简单地 throw
,因为 lambda 主体是单个表达式或块。 throw
是一个语句。
您必须将抛出异常包装到块中:
optStr.ifPresentOrElse(
str -> /*do something*/,
() -> { throw new RuntimeException(); });
还值得一提的是Optional#orElseThrow
,它被设计成实际抛出异常。传递给 Supplier
的唯一参数是实例化异常的方式,如果 Optional
为空,该方法将接受它并抛出而不是你。
optStr.orElseThrow(() -> new RuntimeException());