抛出x扩展Exception方法签名
问题内容:
阅读的JavaDoc
Optional
,我碰到了一个奇怪的方法签名;我一生中从未见过:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X extends Throwable
乍一看,我想知道通用异常怎么<X extends Throwable>
可能发生,因为您不能这样做(here和here)。再三考虑,这开始变得有意义,因为这里只是绑定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
,其势必会Optional
的T
- 我们期望的
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
以后的处理中使用它。