阅读 Optional
的 JavaDoc ,我碰到了一个奇怪的方法签名;我这辈子都没见过:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)
throws X extends Throwable
乍一看,我想知道通用异常 <X extends Throwable>
甚至是可能的,因为你不能这样做( here 和 here )。再想一想,这开始有意义了,因为这里只是为了绑定(bind) Supplier
...但在泛型之前,供应商本身就知道它应该是什么类型。
但第二行打动了我:
-
throws X
是一个完整的通用异常类型。
然后:
-
X extends Throwable
,this到底是什么意思?-
X
已绑定(bind)在方法签名中。
-
- 这会以任何方式解决通用异常限制吗?
- 为什么不直接
throws Throwable
, 因为其余的将通过类型删除被删除?
还有一个不直接相关的问题:
- 此方法是否需要被捕获为
catch(Throwable t)
,或通过提供的Supplier
的类型;因为无法在运行时检查?
最佳答案
像对待你读过的任何其他通用代码一样对待它。
这是我在 Java 8's source code 中看到的正式签名:
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X
X
的上限为Throwable
。这在以后很重要。- 我们返回一个类型
T
,它绑定(bind)到Optional
的T
- 我们期望
Supplier
的通配符上限为X
- 我们抛出
X
(这是有效的,因为X
的上限是Throwable
)。这是在 JLS 8.4.6 中指定的。 ;只要X
被视为Throwable
的子类型,它的声明在这里是有效且合法的。
There is an open bug关于 Javadoc 具有误导性。在这种情况下,最好信任源代码而不是文档,直到错误被宣布修复为止。
至于为什么我们使用 throws X
而不是 throws Throwable
:X
保证绑定(bind)到 Throwable
在最上界。如果您想要更具体的 Throwable
(运行时、已检查或 Error
),那么仅仅抛出 Throwable
不会给您这种灵 active 。
最后一个问题:
Will this method be required to be caught in a catch(Throwable t) clause?
某些东西 必须处理异常,无论是 try...catch
block 还是 JVM 本身。理想情况下,人们希望创建一个绑定(bind)到最能表达他们需求的异常的 Supplier
。您不必(并且可能应该不)为这种情况创建 catch(Throwable t)
;如果您的 Supplier
类型绑定(bind)到您需要处理的特定异常,那么最好将其用作链中稍后的 catch
。
关于java - throws x extends Exception 方法签名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30759692/