Java Optional.orElseThrow 签名解释
Java Optional.orElseThrow signature explanation
出于好奇,我查看了 Optional
class 方法 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")
是一个Supplier<RuntimeException>
。而运行时异常,顾名思义,就是不需要在throws子句中声明的未经检查的异常。
进一步阐明:
具有通用异常(抛出 X)提供了灵活性。
如果您在使用第一个签名时 return 检查异常:
m.orElseThrow(() -> new Exception("ha"));
编译器也给出了错误(未处理的异常),因为它知道可能会抛出一些已检查的异常。但是,提供 RuntimeException 会向编译器表明这是一个未经检查的异常。
另一方面,在您的自定义方法中,您要确保它始终抛出 Throwable
,这需要处理。
出于好奇,我查看了 Optional
class 方法 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")
是一个Supplier<RuntimeException>
。而运行时异常,顾名思义,就是不需要在throws子句中声明的未经检查的异常。
进一步阐明:
具有通用异常(抛出 X)提供了灵活性。
如果您在使用第一个签名时 return 检查异常:
m.orElseThrow(() -> new Exception("ha"));
编译器也给出了错误(未处理的异常),因为它知道可能会抛出一些已检查的异常。但是,提供 RuntimeException 会向编译器表明这是一个未经检查的异常。
另一方面,在您的自定义方法中,您要确保它始终抛出 Throwable
,这需要处理。