从Java 7开始,我们可以使用try-with-resources语句:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
如果br.readLine()
和br.close()
都抛出异常,readFirstLineFromFile
将抛出来自 try block <的异常/ strong>(br.readLine()
除外),以及try-with-resources语句的隐式finally块的异常(br.close()
的例外)将为抑制。
在这种情况下,我们可以通过调用异常的getSuppresed
方法来检索来自隐式finally块的抑制异常像这样的尝试块:
try {
readFirstLineFromFile("Some path here..."); // this is the method using try-with-resources statement
} catch (IOException e) { // this is the exception from the try block
Throwable[] suppressed = e.getSuppressed();
for (Throwable t : suppressed) {
// Check t's type and decide on action to be taken
}
}
但是假设我们必须使用比Java 7更旧的版本编写的方法,其中使用了finally块:
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
然后,如果br.readLine()
和br.close()
再次都抛出异常,情况将会逆转。方法readFirstLineFromFileWithFinallyBlock
将抛出来自 finally块的异常(br.close()
除外),
try block (br.readLine()
除外)的例外情况将被抑制。
所以我的问题是:在第二种情况下,如何从试用块 检索 抑制的例外?
来源:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
答案 0 :(得分:6)
基本上你不能。如果br.close()
抛出,则会丢失被抑制的异常。
你最接近的就是有一个catch
块,它将值赋给locla变量:
static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
IOException exception = null;
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} catch (IOException e) {
exception = e;
} finally {
try {
if (br != null) br.close();
} catch (IOException e) {
// Both the original call and close failed. Eek!
// Decide what you want to do here...
}
// close succeeded, but we already had an exception
if (exception != null) {
throw exception;
}
}
}
...但是此仅处理IOException
(而不是任何未经检查的例外)并且非常混乱。
答案 1 :(得分:1)
来自 try block 的例外(br.readLine()除外)将被抑制。
这不太正确。 Java语言规范writes:
如果由于抛出值V而导致try块的执行突然完成,则可以选择:
如果V的运行时类型与try语句的任何catch子句的可捕获异常类不兼容,则执行finally块。然后有一个选择:
如果finally块正常完成,则由于抛出值V,try语句突然完成。
如果finally块因为S而突然完成,那么try语句突然完成原因S(并抛弃值V并抛弃)。
也就是说,例外是“被丢弃和遗忘”,而不仅仅是被压制。
顺便说一句,由于在Java 7中引入了用于将抑制的异常附加到另一个异常的mechanism,因此Java 6中没有对此进行一般性支持。因此,针对Java 6的代码无法实现使用该功能。