在没有“捕获”的情况下“最终尝试”是否有意义?


127

我看到了一些这样的代码:

    try
    {
        db.store(mydata);
    }
    finally
    {
        db.cleanup();
    }

我以为try应该有一个catch

为什么这段代码这样做呢?


1
它确保清除其他提到的响应,特别是对于文件句柄fopen或数据库连接(也在PHP中)
MediaVince

Answers:


182

如果您希望当前执行的方法仍引发异常,同时允许适当地清理资源,则这很有用。下面是处理调用方法中的异常的具体示例。

public void yourOtherMethod() {
    try {
        yourMethod();
    } catch (YourException ex) {
        // handle exception
    }
}    

public void yourMethod() throws YourException {
    try {
        db.store(mydata);
    } finally {
        db.cleanup();
    }
}

17
通常与锁一起使用,如:lock.lock(); 尝试{/ *锁定* /} {最后lock.unlock()}
分钟

如果最终在内部抛出异常会怎样?
barth,

1
@barth如果没有任何catch块,finally则将在该try块中的任何异常之前执行抛出的异常。因此,如果存在两个例外try,一个finally将被抛出,唯一的例外将被抛出finally。此行为在PHP和Python中是不同的,因为在这些语言中这两种异常将同时抛出,并且异常的顺序是“ try先是然后是” finally
下雨

72

之所以在这里是因为程序员希望确保db.cleanup()即使try块中的代码引发异常也要调用该方法。该块不会处理任何异常,但是它们只会在执行finally块之后向上传播。


23
+1。的try是就在那里允许finally。没有捕获异常。
zockman 2010年

2
+1表示清除该异常一直持续到被捕获为止。谢谢
Code Jockey

20

为什么这段代码这样做呢?

因为显然代码不知道如何在此级别处理异常。很好 -只要调用者之一这样做即可,即只要异常最终在某个地方得到处理。

通常,低级代码无法对异常做出适当的反应,因为需要通知用户,或者必须记录异常,或者必须尝试其他策略。低级代码仅执行一项功能,并且不了解高级决策。

但是代码仍然需要清理其资源(因为如果不清理,它们将会泄漏),因此它只在finally子句中这样做,确保无论是否引发异常,它始终会发生。


2

finally块确保即使抛出RuntimeException(可能由于调用的代码中的某些错误),db.cleanup()也会进行调用。

这通常也用于防止过多的嵌套:

try
{
    if (foo) return false;
    //bla ...
    return true;
}
finally
{
    //clean up
}

特别是当方法返回的点很多时,这将提高可读性,因为任何人都可以看到在每种情况下都将调用清理代码。


0

代码正在执行此操作以确保关闭数据库。
通常,您要执行的方法是将所有数据库访问代码放入try块,然后在finally块中进行调用以关闭数据库。
try ... finally起作用的方式意味着try块中的代码运行,而finally块中的代码在完成时运行...无论如何。
只需将计算机从墙上拉出,最后便会执行。
这意味着,即使调用了异常,并且该方法花了三年时间执行,它仍将进入finally块,并且数据库将关闭。


0

如果try块中的任何代码都可以引发已检查的异常,则它必须出现在方法签名的throws子句中。如果引发了未经检查的异常,则该异常会冒泡退出方法。

无论是否引发异常,都始终执行finally块。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.