我看到了一些像这样的代码:
try
{
db.store(mydata);
}
finally
{
db.cleanup();
}
我认为try
应该有catch
?
为什么这段代码会这样做?
答案 0 :(得分:158)
如果您希望当前正在执行的方法仍然抛出异常,同时允许适当地清理资源,这将非常有用。下面是从调用方法处理异常的具体示例。
public void yourOtherMethod() {
try {
yourMethod();
} catch (YourException ex) {
// handle exception
}
}
public void yourMethod() throws YourException {
try {
db.store(mydata);
} finally {
db.cleanup();
}
}
答案 1 :(得分:67)
它就在那里因为程序员希望确保调用db.cleanup()
,即使try块中的代码抛出异常也是如此。该块不会处理任何异常,但它们只会在执行finally块后向上传播。
答案 2 :(得分:20)
为什么这段代码会这样做?
因为显然代码不知道如何处理此级别的异常。 那很好 - 只要其中一个调用者执行,即只要异常最终在某处处理。
通常,低级代码无法对异常做出适当的反应,因为需要通知用户,或者必须记录异常,或者必须尝试其他策略。低级代码仅执行一个功能,并且不了解更高级别的决策。
但是代码仍然需要清理它的资源(因为如果没有,它们会泄漏),所以它只是在finally
子句中执行,确保总是发生了,是否抛出异常。
答案 3 :(得分:2)
finally块确保即使抛出RuntimeException(可能是由于被调用代码中的某些错误),也会进行db.cleanup()
调用。
这通常也用于防止过多的嵌套:
try
{
if (foo) return false;
//bla ...
return true;
}
finally
{
//clean up
}
特别是当方法返回的点很多时,这提高了可读性,因为任何人都可以看到在每种情况下调用清理代码。
答案 4 :(得分:0)
代码正在执行此操作以确保数据库已关闭
通常,您这样做的方法是将所有数据库访问代码放在try块中,然后调用以关闭finally块中的数据库。
try ...最终运行的方式意味着运行try块中的代码,并且当完成时运行finally块中的代码...无论如何。
如果没有从墙上猛拉的计算机,最终将执行
这意味着即使调用了一个异常,并且该方法需要三年时间才能执行,它仍然会进入finally块并且数据库将被关闭。
答案 5 :(得分:0)
如果try块中的任何代码都可以抛出一个已检查的异常,则它必须出现在方法签名的throws子句中。如果抛出未经检查的异常,则会冒出该方法。
始终执行finally块,无论是否抛出异常。