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

时间:2013-05-10 11:34:06

标签: 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();
    }
}

如果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

2 个答案:

答案 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的代码无法实现使用该功能。