【问题标题】:Java 'finally' clause in a nested 'try' block嵌套“try”块中的 Java“finally”子句
【发布时间】:2020-01-08 09:36:15
【问题描述】:

如果 PrintWriter 抛出异常,是否会执行以下 finally 子句?

try{
   PrintWriter out = new PrintWriter(filename);
   try {
       //output
   } finally {
       out.close();
   }
} catch {
   //handle exception
}

如果 PrintWriter 抛出异常,那么嵌套的 try 块将永远不会被执行,但是为什么嵌套的 finally 子句仍然会被执行执行,即使它被嵌套和跳过?

更新: 我跑了一些测试,如果在嵌套的 try 子句之前抛出异常,那么嵌套的 finally 将不会被执行。 如果在嵌套的 try 子句中抛出异常,则内部的 finally 和外部的 catch 将被执行。

【问题讨论】:

  • finally 块与您的打印作者声明无关
  • PrintWriter implements AutoCloseable 因此,您可以只使用try 和try (PrintWriter out = new PrintWriter(filename)) { ... } catch { ... } 等资源,其中不需要finally(对于out)。内部try 里面有什么可以抛出Exception?
  • 它实际上不会被执行,但不可避免的应用程序崩溃会导致操作系统关闭文件(如果它甚至被创建的话)......

标签: java exception


【解决方案1】:

否,因为之前发生异常时不会到达内部try块,因此也不会到达finally块。

【讨论】:

    【解决方案2】:

    Finally block 无论是否处理异常都会执行。即使它们是一个错误并且到达 catch 块,它也会转到 finally 块来执行这段代码。

    finally 块是用于执行重要代码的块,例如 作为关闭连接,流等。

    所以,在 try{} 块中,您放置了 try 和 finally,但是您询问了外部 try 的捕获,因此它没有进入第一个 try 块。这最终行不通。

    附: : 如果你最后放的是这样的:

         try{
              try{...}
              finally{...}
            }catch(Exception e){...}
            finally{... }
    //in case of exception also , the outside finally is going to work.
    

    P.S.:虽然你得到了你的答案,但是这个概念是供其他天真的程序员参考的

    【讨论】:

      【解决方案3】:

      还可以看到一个更丑陋的变体(有时由 IDE 生成):

      // *** UGLY
      PrintWriter out = null;
      try {
          out = new PrintWriter(filename);
          //output
      } catch (IOException e) {
          //handle exception
      } finally {
          if (out != null) {
              try {
                  out.close();
              } catch (IOException e2) {
                  // IGNORE
              }
          }
      }
      

      这稍微解释了代码:close 也可能抛出 IOException,代码变得繁琐。您的代码仍然需要嵌套异常。

      使用 try-with-resources 可以&应该写成:

      try (PrintWriter out = new PrintWriter(filename)) {
          //output
      } catch (IOException e) {
          //handle exception
      } // Automatically closes.
      

      而且不再嵌套异常。

      最大的好处是不需要捕获任何异常,只需在方法签名中添加throws IOException即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-06
        • 2013-09-01
        • 2018-11-07
        • 2013-11-22
        • 2012-06-17
        • 2015-09-05
        相关资源
        最近更新 更多