dou*_*lep 32 java exception-handling try-finally
使用以下代码:
try {
throw new RuntimeException ("main");
}
finally {
throw new RuntimeException ("finally");
}
Run Code Online (Sandbox Code Playgroud)
我得到这个结果:
Exception in thread "main" java.lang.RuntimeException: finally
at test.main(test.java:12)
Run Code Online (Sandbox Code Playgroud)
但是,通过在Java 7中添加抑制的异常,当finally块本身因异常而失败时,语言将原始"主"异常注册为抑制是不合逻辑的?目前我必须手动模拟这个:
try {
throw new RuntimeException ("main");
}
catch (RuntimeException exception) {
try {
throw new RuntimeException ("finally");
}
catch (RuntimeException exception2) {
exception2.addSuppressed (exception);
throw exception2;
}
}
Run Code Online (Sandbox Code Playgroud)
获得更多有用的(用于了解正在发生的事情)结果:
Exception in thread "main" java.lang.RuntimeException: finally
at test.main(test.java:13)
Suppressed: java.lang.RuntimeException: main
at test.main(test.java:9)
Run Code Online (Sandbox Code Playgroud)
编辑:澄清我在想什么.目前的Java版本是8,抑制异常不是一个全新的功能.但try..finally仍然没有包含它们.有什么东西阻止这种情况发生吗?
因为try-with-resources是语法糖,而Java编译器不会以相同的方式扩展常规的try-finally块.
看看下面的代码:
try(FileInputStream fstream = new FileInputStream("test")) {
fstream.read();
}
Run Code Online (Sandbox Code Playgroud)
编译然后反编译(使用IntelliJ IDEA)时,它看起来像这样:
FileInputStream fstream = new FileInputStream("test");
Throwable var2 = null;
try {
fstream.read();
} catch (Throwable var19) {
var2 = var19;
throw var19;
} finally {
if(fstream != null) {
if(var2 != null) {
try {
fstream.close();
} catch (Throwable var17) {
var2.addSuppressed(var17);
}
} else {
fstream.close();
}
}
}
Run Code Online (Sandbox Code Playgroud)
而这段代码:
FileInputStream fstream = new FileInputStream("test");
try {
fstream.read();
} finally {
fstream.close();
}
Run Code Online (Sandbox Code Playgroud)
在编译和反编译时看起来完全相同.
现在,可以肯定的是,所有finally区块都应该以与上面相同的方式进行扩展,但出于某种原因,这些区块要么被忽视,要么被反对.
我建议你打开一个功能请求,因为我认为这是一个明智的功能.
这不是一个权威的答案,但它看起来像这样的改变要么破坏兼容性,或try-with-resources与try-finally将与相互矛盾.
语义是传播try-with-resources从try块抛出的异常,在调用close()注册为suppress 的方法时抛出异常.从实际的角度来看,这是有道理的,你想要抓住你的"真实"异常,然后如果你愿意,也可以处理没有关闭的资源.
但是在try-finally它中被抛出的异常被finally传播(而一个try被"吞噬"),因此我们可以选择三种不好的解决方案:
try-finally使其try-with-resources与所有以前的代码兼容并破坏代码(或者更确切地说,bug)兼容性.close()"异常,并将try异常注册为suppress,使两个构造彼此不一致.主观上我认为3比1或2差,但是否则很容易争论.但我怀疑这是语言开发人员所面临的两难选择,他们碰巧选择了选项3.
| 归档时间: |
|
| 查看次数: |
1070 次 |
| 最近记录: |