做“ try-finally”而不做“ catch”有意义吗?

我看到一些这样的代码:

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

我以为 trycatch呢?

为什么这个代码是这样的?

88475 次浏览

它之所以存在,是因为程序员希望确保即使 try 块中的代码抛出异常,也会调用 db.cleanup()。任何异常都不会被该块处理,但是它们只会在 finally 块执行后向上传播。如果没有异常,finally 块也将被执行。

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

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


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

为什么这个代码是这样的?

因为显然代码不知道如何处理这个级别的异常。没关系-只要其中一个调用方这样做,也就是说,只要异常最终在某处得到处理。

通常,低级代码不能对异常作出适当的反应,因为需要通知用户,或者必须记录异常,或者必须尝试其他策略。低级代码只执行 功能,不知道高级决策。

但是代码仍然需要清理它的资源(因为如果它不这样做,它们就会泄漏) ,所以它只在 finally子句中这样做,确保发生 一直都是,无论是否抛出异常。

Finally 块确保即使抛出 RuntimeException (可能是由于被调用代码中的某个 bug) ,也会进行 db.cleanup()调用。

这也经常被用来防止过多的筑巢:

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

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

代码这样做是为了确保关闭数据库。
通常,这样做的方法是将所有数据库访问代码放在 try 块中,然后在 finally 块中调用关闭数据库。
Try... finally 工作的方式意味着 try 块中的代码将运行,而 finally 块中的代码将在结束时运行... ... 不管结果如何。
除非计算机被从墙上拽下来,否则最终将执行。
这意味着即使调用了异常,并且该方法需要三年时间才能执行,它仍然会进入 finally 块,数据库也将关闭。

如果 try 块中的任何代码可以抛出检查过的异常,那么它必须出现在方法签名的 throw 子句中。如果抛出一个未检查的异常,它将冒泡出该方法。

不管是否引发异常,finally 块始终执行。