为什么我们使用finally块?

时间:2010-08-06 06:33:44

标签: java .net finally

据我所知,以下两个代码段都将起到同样的作用。为什么要finally阻止?

代码A:

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

代码B:

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

11 个答案:

答案 0 :(得分:128)

  • 如果您未处理的异常被抛出,会发生什么? (我希望你没有抓住Throwable ...)
  • 如果从try块内部返回会发生什么?
  • 如果catch块抛出异常会怎样?

finally块确保然而你退出该块(模式显式地中止整个过程的几种方式),它将被执行。这对于确定性清理资源非常重要。

答案 1 :(得分:10)

请注意(至少在Java中,也可能在C#中),也可以使用try块而不使用catch,但使用finally。当try块中发生异常时,finally块中的代码在异常被抛出之前运行:

InputStream in = new FileInputStream("somefile.xyz");
try {
    somethingThatMightThrowAnException();
}
finally {
    // cleanup here
    in.close();
}

答案 2 :(得分: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();
}

答案 3 :(得分:5)

最后总是被执行,因为你的代码可能不会被捕获。

答案 4 :(得分:2)

即使我们的应用程序被强制关闭,但是如果你在finally块中编写这些代码行,我们必须执行一些任务(如内存释放,关闭数据库,释放锁等)。将执行是否抛出异常......

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

在某些情况下,finally将无法执行,例如JVM Fail,Thread terminate等。

答案 5 :(得分:1)

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

答案 6 :(得分:0)

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

如果必须在每个catch块中放入清理代码,那将太繁琐。

答案 7 :(得分:0)

有时你可能想要执行一段代码。是否抛出异常。然后使用finally

答案 8 :(得分:0)

如果catch块抛出任何异常,那么剩下的代码将不会被执行,因此我们必须写最后一个块。

答案 9 :(得分:0)

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


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

答案 10 :(得分:0)

仍然向下滚动?来啦!

这个问题让我很难过一段时间。

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);
}

在这种情况下,输出为:

  • 最后封锁
  • 消息-不管是什么。

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

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