【问题标题】:Why use finally为什么最终使用
【发布时间】:2011-03-22 06:06:45
【问题描述】:

我从来没有正确理解 finally 语句的用法。谁能告诉我两者之间有什么区别:

try {
    a;
    block;
    off;
    statements;
} catch (Exception e) {
    handle;
    exception;
    e;
} finally {
    do;
    some;
    cleanup;
}

一方面并且:

try {
    a;
    block;
    off;
    statements;
} catch (Exception e) {
    handle;
    exception;
    e;
}
do;
some;
cleanup;

另一方面

【问题讨论】:

    标签: java try-catch-finally


    【解决方案1】:

    在正确的编码风格中,您不想像下面这样一概而论。

    try{
      [some task] 
    }
    catch
    {
    }
    

    您想要做的是捕获特定的已知错误。

    try{
      [some task] 
    }
    catch(Exception ex)
    {
       if([known execption])
         [ignore]
       else
         throw(ex);
    }
    [Cleanup]
    

    在这种情况下,如果再次引发错误,您的清理代码将不会运行。所以我们添加了 finally,即使抛出新的错误也会运行。

    try{
      [some task] 
    }
    catch(Exception ex)
    {
       if([known execption])
         [ignore]
       else
         throw(ex);
    }
    finally
    {
       [Cleanup]
    }
    

    【讨论】:

      【解决方案2】:

      finally 块始终执行。

      finally 块用于清理,例如释放 try/catch 中使用的资源、关闭数据库连接、关闭套接字等。即使在您的 try/@987654327 中发生未处理的异常时也是如此@块。

      finally 块不执行的唯一时间是在try/catch 中调用system.exit() 或发生一些错误而不是异常。

      上面描述的错误是指Java应用程序退出时出现Out Of Memory错误等情况。我看到了一些反对意见 :( 出于这个原因。

      【讨论】:

      • 更正:当抛出 java.lang.Error 时执行 finally 块 is。它可能无法成功执行,但确实会执行。此外,还有其他条件可能会阻碍 finally 块的执行,请参阅我的答案以获得不完整的列表。
      • 注意:如果 JVM 在 try 或 catch 代码正在执行时退出,那么 finally 块可能不会执行。同样,如果执行 try 或 catch 代码的线程被中断或杀死,即使应用程序作为一个整体继续运行,finally 块也可能不会执行。 - docs.oracle.com/javase/tutorial/essential/exceptions/…
      【解决方案3】:

      主要区别在于catch 部分本身可能会抛出异常、跳出周围的块或从当前方法返回。在这种情况下,do; some; cleanup; 不会被执行。

      使用finally 块,保证该代码将被执行。

      【讨论】:

      • 终于保证执行了吗? stackoverflow.com/questions/464098/…
      • 是的,不是 System.exit(),这是真的。或者,你知道,JVM 崩溃。
      • ... 或死锁,或 ... - 真正的规则是:当/如果 try-(catch)-finally 语句完成时,finally-block 保证已执行。跨度>
      【解决方案4】:

      捕获所有异常基本上是一个坏主意 - 因此您需要考虑如果未捕获的异常从您的 try/catch 或 try/catch/finally 块中传播出去会发生什么。 finally 块允许您在退出时进行清理。

      还有:

      • catch 块可能会引发异常
      • 您可能希望从 try 块返回

      简而言之,如果你希望在离开 try/catch 块时执行某些代码然而你要离开它(除了进程被非常艰难地终止),finally 是你的朋友.

      【讨论】:

        【解决方案5】:

        “finally”块将始终执行。

        在您的第二个示例中,如果 catch 块重新引发异常,或者在 try 块中发生未捕获的异常,则不会发生清理。

        【讨论】:

        • finally 没有执行的情况有很多(参见我的回答),但你说得对,抛出异常(或使用控制流语句)不在其中。
        【解决方案6】:

        来自thisGeekInterview 论坛:

        finally 块总是在 try 块退出时执行。这样可以确保即使发生意外异常也会执行 finally 块。但 finally 不仅仅对异常处理有用——它允许程序员避免清理代码意外地被 return、continue 或 break 绕过。将清理代码放在 finally 块中始终是一个好习惯,即使没有预料到异常也是如此。

        【讨论】:

          【解决方案7】:

          简单的一行解释:

          无论您是否捕获到异常,finally 块中的代码都会被执行。

          您在此处给出的两部分之间的差异是:未使用 finally 的部分中的代码将永远不会被执行。

          要正确理解finally,您只需要知道finally = 保证!

          您可以使用它来清理、帮助用户友好或重试某些事情

          【讨论】:

          • 这确实很旧,但不能保证 finally 会执行。快速示例是 System.exit(0);还有更多示例我不会列出,我相信已经在其他答案中列出。
          【解决方案8】:

          在第一个示例中,即使在 try 子句中有 return 语句,finally 块也会始终执行。唯一没有被执行的是当你有 System.exit(0) 时。

          【讨论】:

          • 还有许多其他条件不执行 finally,c.f.我的回答(并没有声称给所有这些......)
          【解决方案9】:

          如果

          • try-block 通过抛出不是java.lang.Exceptionjava.lang.Throwable 来完成,例如因为它是java.lang.Error,例如AssertionErrorOutOfMemoryError
          • try 块使用continuebreakreturn 等控制流语句突然完成
          • catch 块突然完成(通过抛出任何可抛出对象或使用控制流语句)

          更一般地说,java 语言保证在 try 语句完成之前执行 finally 块。 (请注意,如果 try-statement 没有完成,则无法保证 finally。一个语句可能由于各种原因而无法完成,包括硬件关闭、OS 关闭、VM 关闭(例如由于 System.exit),线程正在等待(Thread.suspend()synchronizedObject.wait()Thread.sleep())或正忙(无休止的循环,,,,)。

          所以,finally 块是比方法体末尾更好的清理动作的地方,但它本身仍然不能保证清理执行。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-11-11
            • 2012-09-06
            • 1970-01-01
            • 1970-01-01
            • 2016-01-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多