为什么在以下情况下throw e
允许,但不允许?throw a
void test() {
try {
System.out.println();
} catch (Error | RuntimeException e) {
var a = e;
//throw a; unreported exception Throwable; must be caught or declared to be thrown
throw e;
}
}
所有这些直观上都是有道理的,但从JLS 14.20
多 catch 子句可以看作是一系列单 catch 子句。也就是说,异常参数类型表示为联合的 catch 子句等同
D1|D2|...|Dn
于一系列n 个catch 子句,其中异常参数的类型分别为类类型。在每个n 个D1, D2, ..., Dn
catch 子句的 Block 中,异常参数的声明类型为。lub(D1, D2, ..., Dn)
因为lub(Error,RuntimeException)
是Throwable
,上面的代码应该等同于:
try {
System.out.println();
} catch (Error e) {
Throwable lub = e;
throw lub;
} catch (RuntimeException e) {
Throwable lub = e;
throw lub;
}
(这显然不能编译)
此外, 的类型“当被视为未出现在赋值上下文中时”a
是 的类型( JLS 14.4.1),但如上所示,它与 的类型不同。e
e
我是否忽略了什么?
编辑:这不是为什么在某些情况下重新抛出 Throwable 而不声明它是合法的?的重复,因为这个问题特定于多重捕获(这里没有讨论),并且由于对 JLS 中解决多重捕获的特定片段的误解而出现。这个问题提供的答案帮助我把这些点联系起来:)