为什么 Java 中的 multi-catch 功能要求异常是最终的?
Why does multi-catch feature in Java require exceptions to be final?
关于 multi-catch feature 添加到 Java 7 的 Oracle 文档指出 catch
子句中的异常参数隐含地 final
.
我的问题是:这样的限制有什么意义?因为我似乎找不到它带来的任何关键改进。将引用对象标记为 final
仅保护引用本身不被修改,而不是它引用的对象,并且永远不会禁止创建另一个引用并以任何他们想要的方式修改它。
A somewhat relevant question on SO 讨论了为什么在 catch
子句中修改异常引用不是最明智的做法,但它与 any 相关使用 catch
子句,而不仅仅是它的 multi-catch 形式。那么,为什么 Java 为 multi-catch 设置一个异常并以特殊方式处理它?
在uni-catch 子句中,您可以自由地重新分配异常对象。例如,这很好用:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException) {
e = new IOException(); // this is acceptable (although there is no point in doing it)
e.printStackTrace();
}
编译器肯定知道抛出的对象是IOException
类型。
然而,在 multi-catch 子句中,你可以有这样的东西:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException | ParserException e) {
e = new IOException(); // this is NOT acceptable -- e may reference a ParserException
e.printStackTrace();
}
在这种情况下,编译器在编译时不知道异常是哪种类型,因此将新的IOException
分配给可以引用或者的变量不应允许 IOException
或 ParseException
。除此之外,首先缺少分配给异常变量的用例。因此,使变量隐式 final
并避免所有这些混淆是非常有意义的。如果你真的需要给变量赋值,你可以切换到旧的catch
块序列的写法。
关于 multi-catch feature 添加到 Java 7 的 Oracle 文档指出 catch
子句中的异常参数隐含地 final
.
我的问题是:这样的限制有什么意义?因为我似乎找不到它带来的任何关键改进。将引用对象标记为 final
仅保护引用本身不被修改,而不是它引用的对象,并且永远不会禁止创建另一个引用并以任何他们想要的方式修改它。
A somewhat relevant question on SO 讨论了为什么在 catch
子句中修改异常引用不是最明智的做法,但它与 any 相关使用 catch
子句,而不仅仅是它的 multi-catch 形式。那么,为什么 Java 为 multi-catch 设置一个异常并以特殊方式处理它?
在uni-catch 子句中,您可以自由地重新分配异常对象。例如,这很好用:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException) {
e = new IOException(); // this is acceptable (although there is no point in doing it)
e.printStackTrace();
}
编译器肯定知道抛出的对象是IOException
类型。
然而,在 multi-catch 子句中,你可以有这样的东西:
try {
... // code that can throw IOException or some user-defined ParserException
} catch(IOException | ParserException e) {
e = new IOException(); // this is NOT acceptable -- e may reference a ParserException
e.printStackTrace();
}
在这种情况下,编译器在编译时不知道异常是哪种类型,因此将新的IOException
分配给可以引用或者的变量不应允许 IOException
或 ParseException
。除此之外,首先缺少分配给异常变量的用例。因此,使变量隐式 final
并避免所有这些混淆是非常有意义的。如果你真的需要给变量赋值,你可以切换到旧的catch
块序列的写法。