通过Optional#orElseThrow正确使用lambda表达式

时间:2019-02-14 11:45:22

标签: java functional-interface

考虑以下简单示例:

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确定正确的类型是否正确?

1 个答案:

答案 0 :(得分:2)

如果第一个示例可行,请考虑以下事项:

Supplier<InterruptedException> s = this::exceptionSupplier;

如果您这样调用,它将失败并显示ClassCastException

InterruptedException e = s.get();

这是因为X是在呼叫站点上确定的。编译器插入了一个隐式强制转换:

InterruptedException e = (InterruptedException) s.get();

但是,当然,s返回一个RuntimeException,它不能转换为InterruptedException

如果要返回RuntimeException,则将方法的返回类型设为RuntimeException,不需要类型变量。