使用 Optional#orElseThrow 正确使用 lambda 表达式
Correct use of lambda expression with Optional#orElseThrow
考虑以下简单示例:
Optional.empty().orElseThrow(this::exceptionSupplier);
IntelliJ 为供应商生成如下方法,但它无法编译!
private <X extends Throwable> X exceptionSupplier() {
return new RuntimeException();
}
不兼容的类型。
要求:X
找到:java.lang.RuntimeException
如果我将签名更改为以下内容,它就可以工作了。
private Exception exceptionSupplier() {
return new RuntimeException();
}
编译器无法确定 X
的正确类型是否正确?
如果第一个示例有效,请考虑以下事项:
Supplier<InterruptedException> s = this::exceptionSupplier;
如果你这样调用它,这将失败并显示 ClassCastException
:
InterruptedException e = s.get();
这是因为X
是在调用站点确定的。编译器插入了一个隐式转换:
InterruptedException e = (InterruptedException) s.get();
但是,当然,s
return 你是 RuntimeException
,不能转换为 InterruptedException
。
如果你想return一个RuntimeException
,使方法的return类型RuntimeException
,不需要类型变量。
考虑以下简单示例:
Optional.empty().orElseThrow(this::exceptionSupplier);
IntelliJ 为供应商生成如下方法,但它无法编译!
private <X extends Throwable> X exceptionSupplier() {
return new RuntimeException();
}
不兼容的类型。 要求:X 找到:java.lang.RuntimeException
如果我将签名更改为以下内容,它就可以工作了。
private Exception exceptionSupplier() {
return new RuntimeException();
}
编译器无法确定 X
的正确类型是否正确?
如果第一个示例有效,请考虑以下事项:
Supplier<InterruptedException> s = this::exceptionSupplier;
如果你这样调用它,这将失败并显示 ClassCastException
:
InterruptedException e = s.get();
这是因为X
是在调用站点确定的。编译器插入了一个隐式转换:
InterruptedException e = (InterruptedException) s.get();
但是,当然,s
return 你是 RuntimeException
,不能转换为 InterruptedException
。
如果你想return一个RuntimeException
,使方法的return类型RuntimeException
,不需要类型变量。