在下面的代码片段中,如果抛出ex1,将被第二个catch块捕获,还是会被抛回到方法的调用者?
如果它被抛回到调用者,然后在finally块(ex2)中发生第二个异常,这是否意味着2个异常将被抛回调用者(ex1和ex2)?
try {
// write to file
} catch (IOException ex1) {
throw ex1;
} finally {
try {
aBufferedWriter.close();
} catch (IOException ex2) {
throw ex2;
}
}
答案 0 :(得分:6)
这两个例外都将被抛回调用者......虽然在任何特定情况下都是一个例外。如果外部try块的主体抛出然后close
抛出,则调用者只能看到第二个异常。
然而,仅仅重新抛出catch
块是毫无意义的。您的代码将更加清晰:
try {
// write to file
} finally {
aBufferedWriter.close();
}
在Java 7中,try-with-resources statement可以自动执行此操作:
try (BufferedWriter writer = new BufferedWriter(...)) {
// Use the writer here
} // The writer is auto-closed here
通过这种方式,您可以 使用Throwable.getSuppressed
与主体中的异常分开关闭异常。
答案 1 :(得分:0)
取决于设计。你也可以尝试
try{
try{
//write to file
}finally{
aBufferedWriter.close();
}
}catch(IOException e){
}
如果你想抛出异常,也可以抓住异常。
答案 2 :(得分:0)
Q值。在下面的代码片段中,如果抛出ex1,将被第二个catch块捕获,还是会被抛回到方法的调用者?
不,它不会被catch
内的finally
块捕获,只要finally块中没有异常,因此异常ex1
将被抛回调用方法。
Q值。如果它被抛回到调用者,然后在finally块(ex2)中发生第二个异常,这是否意味着2个异常将被抛回调用者(ex1和ex2)?
在这种情况下,由于在finally块中抛出异常,它将覆盖外部catch块中抛出的异常,并导致异常ex2
被抛回调用方法。
只有一个异常会被抛回到调用方法中以便单次执行,而不是两者。话虽如此,拥有一个catch
块只是为了抛弃已被捕获的异常,实在是毫无意义。
答案 3 :(得分:0)
在Java 7之前,真正准确的模式是
public void writeToFile(String file) throws IOException {
IOException exception = null;
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} catch (IOException ex) {
// store exception for later rethrow
exception = ex;
} finally {
try {
out.close();
} catch (IOException ex) {
// do NOT supress 'outer' exception:
if (exception == null) {
exception = ex;
}
}
}
if (exception != null) {
throw exception;
}
}
看起来很疯狂,但这涵盖了所有可能性并绕过异常抑制异常(当finally
语句中抛出异常时,它会抑制try
块中发生的'真正'异常 - 如果有)。
但也许 - 为了便于阅读 - 你可以忍受被抑制的异常,并按照这样做:
OutputStream out = new FileOutputStream(file);
try {
// TODO: write data to file
} finally {
out.close(); // if an exception is thrown here, it hides the original exception
}
另见http://tutorials.jenkov.com/java-exception-handling/exception-handling-templates.html
从Java 7 开始,您可以使用try-with-resource语句(几乎)执行相同操作:
public void writeToFile(String file) throws IOException {
try (OutputStream out = new FileOutputStream(file)) {
// TODO: write data to file
}
}
请注意,关闭资源时抛出的异常不会抑制原始异常。而是将这些额外的异常作为“抑制异常”添加到基本异常中。您可以使用baseException.getSuppressed()
(Java 7及更高版本)获取它们。
另见http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html