抛出x扩展Exception方法签名


问题内容

阅读的JavaDoc
Optional,我碰到了一个奇怪的方法签名;我一生中从未见过:

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
                                throws X extends Throwable

乍一看,我想知道通用异常怎么<X extends Throwable>可能发生,因为您不能这样做(herehere)。再三考虑,这开始变得有意义,因为这里只是绑定Supplier…,但是供应商本身确切知道泛型之前应该是什么类型。

但是第二行打给我:

  • throws X 是完整的通用异常类型。

然后:

  • X extends Throwable什么世界呢 是什么意思?
    • X 已绑定在方法签名中。
  • 这将以任何方式解决通用异常限制吗?
  • 为什么不这样做throws Throwable,因为其余的将通过类型擦除来擦除?

和一个不直接相关的问题:

  • 是否要求将此方法捕获为catch(Throwable t),或按提供Supplier的类型捕获?因为无法在运行时检查?

问题答案:

像对待您阅读的任何其他通用代码一样对待它。

这是我在Java
8的源代码中
看到的正式签名:

public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
  • X的上限为Throwable。稍后这将很重要。
  • 我们返回一个类型T,其势必会OptionalT
  • 我们期望的Supplier通配符上限为X
  • 我们抛出X(这是有效的,因为X其上限为Throwable)。这在JLS 8.4.6中指定;只要X被视为的子类型Throwable,则其声明在此是有效且合法的。

关于Javadoc的误导存在一个公开的错误。在这种情况下,最好是信任源代码而不是文档,直到该错误被声明为已修复。

至于为什么我们使用throws X而不是throws Throwable
X一定要绑定到Throwable最上层。如果您想要更具体的内容Throwable(运行时,检查的或Error),那么仅仅抛出Throwable将不会给您带来灵活性。

最后一个问题:

是否需要在catch(Throwable t)子句中捕获此方法?

__链下的 某些事物
必须处理异常,例如是try...catch块还是JVM本身。理想情况下,人们希望创建一个Supplier可以最好地传达其需求的异常的绑定。你不必(并且可能应该
不是 )创建一个catch(Throwable t)针对这种情况;
如果您Supplier的类型绑定到需要处理的特定异常,那么最好在catch以后的处理中使用它。