从Java 7开始,我们可以使用try-with-resources语句:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
Run Code Online (Sandbox Code Playgroud)
如果br.readLine()和br.close() 两个抛出异常,readFirstLineFromFile将从try块抛出异常(异常),并且将禁止来自try-with-resources语句的隐式finally块(异常)的异常.br.readLine()br.close()
在这种情况下,我们可以通过从try块的异常调用方法来从隐式finally块中检索抑制的异常,如下所示:getSuppresed
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
}
}
Run Code Online (Sandbox Code Playgroud)
但是假设我们必须使用比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();
}
}
Run Code Online (Sandbox Code Playgroud)
那么如果br.readLine()和br.close()一次都抛出异常,这种情况将得到扭转.该方法readFirstLineFromFileWithFinallyBlock将抛出从异常最后块(除外br.close()),以及从异常try块(除外br.readLine())将被抑制.
所以在这里我的问题是:我们如何才能找回了抑制异常从try块在第二种情况下?
资料来源:http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
基本上你不能.抛出时会丢失被抑制的异常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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
...但这仅处理IOException(而不是任何未经检查的例外)并且非常混乱.