在Java中使用Readers和Streams总是让我感到困惑的一件事是该close()方法可以抛出异常.因为将close方法放在finally块中是个好主意,这需要一些尴尬的情况.我通常使用这种结构:
FileReader fr = new FileReader("SomeFile.txt");
try {
try {
fr.read();
} finally {
fr.close();
}
} catch(Exception e) {
// Do exception handling
}
Run Code Online (Sandbox Code Playgroud)
但我也看到了这种结构:
FileReader fr = new FileReader("SomeFile.txt");
try {
fr.read()
} catch (Exception e) {
// Do exception handling
} finally {
try {
fr.close();
} catch (Exception e) {
// Do exception handling
}
}
Run Code Online (Sandbox Code Playgroud)
我更喜欢第一个结构,因为只有一个挡块,它看起来更优雅.是否有理由更喜欢第二种或替代结构?
更新:如果我指出两者read并且close只抛出IOExceptions ,它会有所作为吗?因此,在我看来,如果读取失败,关闭将因同样的原因而失败.
我有一个工作流方法,并在发生错误时抛出异常.我想将报告指标添加到我的工作流程中.在下面的finally块中,有没有办法判断try/catch块中的一个方法是否引发了异常?
我可以添加自己的catch/throw代码,但更喜欢更清晰的解决方案,因为这是我在项目中重用的模式.
@Override
public void workflowExecutor() throws Exception {
try {
reportStartWorkflow();
doThis();
doThat();
workHarder();
} finally {
/**
* Am I here because my workflow finished normally, or because a workflow method
* threw an exception?
*/
reportEndWorkflow();
}
}
Run Code Online (Sandbox Code Playgroud) 使用以下代码:
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仍然没有包含它们.有什么东西阻止这种情况发生吗?