100

据我所知,以下两个代码片段都将用于相同的目的。为什么有finally块?

代码 A:

try { /* Some code */ }
catch { /* Exception handling code */ }
finally { /* Cleanup code */ }

代码 B:

try { /* Some code */ }
catch { /* Exception handling code */ }
// Cleanup code
4

11 回答 11

149
  • 如果抛出一个你没有处理的异常会发生什么?(我希望你没有抓到Throwable......)
  • 如果你从 try 块内返回会发生什么?
  • 如果 catch 块抛出异常会发生什么?

一个finally块确保无论您退出该块(以几种显式中止整个过程的方式为模),它都会被执行。这对于资源的确定性清理很重要。

于 2010-08-06T06:36:50.760 回答
13

请注意(至少在 Java 中,也可能在 C# 中)也可以有一个try没有 a 的块catch,但有一个finally. 当块中发生异常时,try块中的代码在finally异常被向上抛出之前运行:

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}
于 2010-08-06T06:57:29.720 回答
7

无论您的 try 或 catch 块中发生了什么,您可能都希望放置您想要执行的代码。

此外,如果您使用多个 catch 并且如果您想放置一些对于所有 catch 块都通用的代码,这将是一个放置的地方 - 但您不能确定 try 中的整个代码是否已执行。

例如:

conn c1 = new connection();
try {
    c1.dosomething();
} catch (ExceptionA exa) {
    handleexA();
    //c1.close();
} catch (ExceptionB exb) {
    handleexB();
    //c1.close();
} finally {
    c1.close();
}
于 2010-08-06T07:36:02.190 回答
5

finally 总是被执行,而你的代码在 catch 之后可能不会。

于 2010-08-06T06:36:37.457 回答
2

即使我们的应用程序被强制关闭,也会有一些我们必须执行的任务(如内存释放、关闭数据库、释放锁等),如果您在finally块中编写这些代码行,无论是否抛出异常,它都会执行不是...

你的应用程序可能是线程的集合,Exception终止线程而不是整个应用程序,在这种情况下finally更有用。

在某些情况下finally不会执行,例如 JVM Fail、Thread terminate 等。

于 2012-09-12T10:11:29.550 回答
1

因为无论可能引发任何异常,您都需要执行该代码。例如,您可能需要清理一些非托管资源('using' 构造编译为 try/finally 块)。

于 2010-08-06T06:36:37.537 回答
1

还在向下滚动?干得好!

这个问题给了我一段时间的艰难时光。

try
{
 int a=1;
 int b=0;
 int c=a/b;
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}
finally
{
 console.writeline("Finally block");
}
console.writeline("After finally");

在上述情况下会打印什么?是的,没猜错:

  • ex.Message——不管它是什么(可能试图除以零)

  • 最后阻塞

  • 终于之后

    try
    {
        int a=1;
        int b=0;
        int c=a/b;
    }
    catch(Exception ex)
    {
        throw(ex);
    }
    finally
    {
        console.writeline("Finally block");
    }
    console.writeline("After finally");
    

这会打印什么?没有什么!由于 catch 块引发错误,因此引发错误。

在一个良好的编程结构中,您的异常将被汇集,从某种意义上说,此代码将从另一层处理。为了刺激这种情况,我将嵌套尝试此代码。

try
{    
 try
    {
     int a=1;
     int b=0;
     int c=a/b;
    }
    catch(Exception ex)
    {
     throw(ex);
    }
    finally
    {
     console.writeline("Finally block")
    }
    console.writeline("After finally");
}
catch(Exception ex)
{
 console.writeline(ex.Message);
}

在这种情况下,输出将是:

  • 最后阻塞
  • ex.Message——不管它是什么。

很明显,当您捕获异常并将其再次抛出到其他层(Funneling)时,抛出后的代码不会被执行。它的作用类似于函数内部的 return 工作方式。

您现在知道为什么不在 catch 块之后关闭代码上的资源了。将它们放在 finally 块中。

于 2019-12-30T20:23:59.603 回答
0

finally总是执行,除非 JVM 被关闭,finally只是提供一种方法将清理代码放在一个地方。

如果您必须将清理代码放在每个catch块中,那就太乏味了。

于 2010-08-06T06:37:26.917 回答
0

有时您可能无论如何都想执行一段代码。是否抛出异常。然后一个使用finally.

于 2010-08-06T06:41:25.010 回答
0

java中的finally块可用于放置“清理”代码,例如关闭文件、关闭连接等。


如果程序退出(通过调用 System.exit() 或通过导致导致进程中止的致命错误),将不会执行 finally 块。

于 2019-03-10T18:28:04.887 回答
0

如果 catch 块抛出任何异常,那么剩余的代码将不会执行,因此我们必须编写 finaly 块。

于 2016-06-09T11:15:21.490 回答