Boa*_*ann 16 java exception throw language-lawyer checked-exceptions
我偶然注意到这个throw语句(从一些更复杂的代码中提取)编译:
void foo() {
try {
} catch (Throwable t) {
throw t;
}
}
Run Code Online (Sandbox Code Playgroud)
对于一个短暂而快乐的时刻,我认为已经检查过的异常最终决定已经死了,但它仍然在这方面很高兴:
void foo() {
try {
} catch (Throwable t) {
Throwable t1 = t;
throw t1;
}
}
Run Code Online (Sandbox Code Playgroud)
该try块不必为空; 它似乎可以有代码,只要该代码不会抛出已检查的异常.这似乎是合理的,但我的问题是,语言规范中的哪些规则描述了这种行为?据我所知,§14.18town语句明确禁止它,因为t表达式的类型是一个已检查的异常,并且它没有被捕获或声明被抛出.(?)
Kep*_*pil 13
这是因为Java 7中引入的Project Coin中包含的更改允许通过重新抛出原始异常来进行常规异常处理.这是一个适用于Java 7但不适用于Java 6的示例:
public static demoRethrow() throws IOException {
try {
throw new IOException("Error");
}
catch(Exception exception) {
/*
* Do some handling and then rethrow.
*/
throw exception;
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处阅读解释更改的整篇文章.
我认为,在措辞§14.18的throw声明,你指的是在JLS一个错误-应该已经更新了Java SE 7中,而不是文字.
描述预期行为的JLS文本位于第11.2.2节语句的异常分析中:
一
throw,其抛出的表达式语句是最终或有效决赛异常参数catch根据条款C可以抛出一个异常,E级IFF:
- E是一个异常类,声明C
try的try语句块可以抛出; 和- E的赋值与C的任何可捕获异常类兼容; 和
- E与赋值
catch在同一try语句中C的左侧的子句的任何可捕获异常类不兼容.
第一个要点是相关要点; 因为catch-clause参数t实际上是最终的(意味着它从未被赋值或递增或递减;参见§4.12.4 final变量),throw t只能抛出try块可以抛出的东西.
但正如您所说,§14.18中的编译时检查不会对此作出任何限制.§11.2.2不决定允许什么,不允许什么; 相反,它应该是对可以抛出的各种限制的后果的分析.(这种分析确实反馈到规范的更规范的部分 - §14.18本身在其第二个子弹点中使用它 - 但§14.18不能只说"如果它抛出一个它不能的例外它是一个编译时错误抛出§11.2.2",因为这将是循环的.)
所以我认为需要调整§14.18以适应§11.2.2的意图.
很好找!
| 归档时间: |
|
| 查看次数: |
582 次 |
| 最近记录: |