【问题标题】:What is the benefit to use "finally" after try-catch block in java? [closed]在 java 中的 try-catch 块之后使用“finally”有什么好处? [关闭]
【发布时间】:2013-04-02 15:56:10
【问题描述】:

“finally”块总是在 try-catch 结束时执行,无论是否发生异常。 但也总是执行 try-catch 之外和之后的每一行代码。 那么,为什么要使用 finally 语句呢?

例子:

try {
    //code...
} catch (Exception e) {
    //code...
} finally {
    System.out.println("This line is always printed");
}
System.out.println("Also this line is always printed !! So why to use 'finally'?? ");

【问题讨论】:

  • 使用 catch (Throwable t) 而不是 catch (Exception e) 总是会执行最后一行。
  • 在 catch 块中抛出新异常是一种常见的模式,最后让您在发出新异常之前清理 try 块中的内容。它非常方便。该符号还使代码更具语义。

标签: java try-catch finally


【解决方案1】:

最有用的情况是当你需要释放一些资源时:

InputStream is = ...
try {
    //code...
} catch (Exception e) {
    //code...
} finally {
    is.close();
}

更一般地说,当你想确保你的代码在最后执行时使用它,即使在执行过程中出现异常:

long startTime = System.currentTimeMillis();
try {
    //code...
} catch (Exception e) {
    //code...
} finally {
    long endTime = System.currentTimeMillis();
    System.out.println("Operation took " + (endTime-startTime) + " ms");
}

这个finally总是被执行的想法是,整个块之后的第一行不是这种情况

  • 如果catch 块允许一些可投掷的传球
  • 如果它重新抛出异常,这是非常频繁的

【讨论】:

    【解决方案2】:

    最后一个System.out.println(在finally块之后)只有在try块中抛出的异常被catch块实际捕获并且执行没有被例如中断时才会运行。返回声明。

    在您的示例中,finally 块将始终运行,但如果在 try 块中没有抛出 Error(它不会被捕获),则执行只会在 finally 块之后继续执行,如果没有 Throwable 是在catch块中抛出,没有其他语句,会中断执行。

    【讨论】:

      【解决方案3】:

      而且在 try-catch 之外和之后的每一行代码也总是被执行。

      嗯,并非总是如此。例如,我们可以抛出 Error,它不是异常的子类型,而是 Throwable,因此它不会被 catch(Exception e) {..} 捕获。在这种情况下,try 块之前的块会将控制流移出方法,相应的finally 部分将被调用,但代码之后它不会。

      看看这段代码

      public static void main(String[] args) {
          try{
              //...
              throw new Error("something went terribly wrong");
          } catch (Exception e) {//will NOT catch Error
              e.printStackTrace();
          } finally{//this will be invoked regardless of what happens in try,              
              System.out.println("finally block");
          }
      
          //if Error will be thrown in above `try` it will move flow of control 
          //from this method, which will prevent it from reaching 
          //this place and executing code after this comment
          System.out.println("after finally... may not be executed");
      }
      

      【讨论】:

      • Aarath 问题中的示例代码会捕获 RuntimeException。在这种情况下,finally 块之后的代码也会运行。
      • @jarnbjo 然后程序可以抛出RuntimeException 而不是Error,这也是未选中的。现在你可能会说它可以通过捕获Throwable 来处理,但这真的是真实程序的工作原理吗?如果我们开始捕获所有错误,那么我们真的不需要 finally 部分,因为我们可以在每个 catch 块的末尾和 try-catch 部分之后移动它,以防没有执行任何捕获。
      • 您的问题是您试图使用非常狭窄的解释来解释一般行为,这只涵盖了非常具体的原因。在某些情况下,代码执行将不会继续超过 finally 块,例如如果在 try 块中抛出任何异常并且没有被匹配的 catch 块捕获(如果它是运行时异常或未经检查的异常完全不相关),如果在 catch 块中抛出新异常或者如果代码执行被任何中断其他声明,例如try 块中的 return 语句。
      • @jarnbjo OP 询问为什么他应该使用 finally 块,因为他认为 try-catch 之后的所有内容都会被执行。向他表明,一个简单的例子并不总是正确的,你不觉得吗?
      • 不,最好解释一下为什么他的说法是错误的。
      【解决方案4】:

      finally 块是防止资源泄漏的关键工具。什么时候 关闭文件或以其他方式恢复资源,将代码放在 finally 块以确保资源总是被回收。

      但 finally 不仅仅对异常处理有用——它 允许程序员避免意外清理代码 被返回、继续或中断绕过。将清理代码放入 finally 块总是一个好习惯,即使没有例外 预计。

      更多here

      【讨论】:

        【解决方案5】:

        假设您正在写入文件,突然它会创建一个异常,即您如何关闭文件。然后最终帮助您,并且对于数据库事务 finally 块有很大帮助

        【讨论】:

          【解决方案6】:

          finally 块的唯一目的是关闭你在 try 块中打开的资源。 资源可以是数据库连接、文件写入/读取等:

          Connection conn= null;
          try {
           conn= get the db conn;
          //do some DML/DDL
          }
          catch(SQLException ex) {
          
          }
          finally {
          conn.close();
          }
          

          【讨论】:

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