首页 > 解决方案 > 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"
}
  1. try-catch为什么没有阻止我的方法不被接受?

  2. 为什么在原始方法中扩展Throwable不需要 try-catch块,即使原始方法抛出一个Throwable对象?

标签: javagenericsoptionalparameterized-constructor

解决方案


  1. 因为编译器只知道你的方法是抛出一个 Throwable。由于 Throwable 因此可能是一个检查异常,因此您不得不在 throws 子句中声明它或捕获它。

  2. 因为编译器知道该方法抛出 X,其中泛型类型 X 被推断为RuntimeException: () -> new RuntimeException("ha")is a Supplier<RuntimeException>。根据定义,运行时异常是未经检查的异常,不需要在 throws 子句中声明。


推荐阅读