如何检索'try'块中的抑制异常?

Hải*_*ong 6 java exception

从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

Jon*_*eet 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;
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

...但这处理IOException(而不是任何未经检查的例外)并且非常混乱.