java - Java Optional.orElseThrow 签名说明
问题描述
出于好奇,我查看了Optional
类方法,但对它的签名感到困惑。orElseThrow
我不明白为什么必须按原样声明它。orElseThrow
所以,我用原始方法的副本和我的简化变体做了一个实验:
public class Main<T> {
//This is original signature of Optional.orElseThrow method
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X{
throw exceptionSupplier.get();
}
//This is my attempt to simplify it but it doesn't work without try-catch block
public T orElseThrow2(Supplier<Throwable> exceptionSupplier) throws Throwable{
throw exceptionSupplier.get();
}
public static void main(String[] args){
Main<Object> m = new Main<Object>();
m.orElseThrow(() -> new RuntimeException("ha")); //no warnings/errors shown
m.orElseThrow2(() -> new RuntimeException("sad")); //"Unhandled exception: java.lang.Throwable"
}
try-catch
为什么没有阻止我的方法不被接受?为什么在原始方法中扩展
Throwable
不需要try-catch
块,即使原始方法抛出一个Throwable
对象?
解决方案
因为编译器只知道你的方法是抛出一个 Throwable。由于 Throwable 因此可能是一个检查异常,因此您不得不在 throws 子句中声明它或捕获它。
因为编译器知道该方法抛出 X,其中泛型类型 X 被推断为
RuntimeException
:() -> new RuntimeException("ha")
is aSupplier<RuntimeException>
。根据定义,运行时异常是未经检查的异常,不需要在 throws 子句中声明。
推荐阅读
- javascript - 如何使用 php/javascript 仅显示 url 中的特定参数?
- amazon-web-services - 如何在 aws-sam template.yaml 文件中添加插件
- omnet++ - 如何在 Veins 中发送二进制数据
- android - 如何将字符串日期解析为其他时区的其他日期
- r - 如何以双射方式对称 [0,1]^d 中的数据集
- swift - 无法为特定设备自定义 UITableViewCell
- android - (Android) 在 Xamarin Forms 3.3 上更改模块时总是显示启动画面?
- java - Lombok 的 @NonNull 在验证期间干扰 javax.validation.constraints.NotNull
- asp.net - 回收应用程序池时多次出现signalr 400错误
- ios - UNNotification 的重复间隔