我看到一些这样的代码:
try { db.store(mydata); } finally { db.cleanup(); }
我以为 try是 catch呢?
try
catch
为什么这个代码是这样的?
它之所以存在,是因为程序员希望确保即使 try 块中的代码抛出异常,也会调用 db.cleanup()。任何异常都不会被该块处理,但是它们只会在 finally 块执行后向上传播。如果没有异常,finally 块也将被执行。
db.cleanup()
如果您希望当前正在执行的方法仍然引发异常,同时允许适当清理资源,那么这很有用。下面是处理来自调用方法的异常的具体示例。
public void yourOtherMethod() { try { yourMethod(); } catch (YourException ex) { // handle exception } } public void yourMethod() throws YourException { try { db.store(mydata); } finally { db.cleanup(); } }
因为显然代码不知道如何处理这个级别的异常。没关系-只要其中一个调用方这样做,也就是说,只要异常最终在某处得到处理。
通常,低级代码不能对异常作出适当的反应,因为需要通知用户,或者必须记录异常,或者必须尝试其他策略。低级代码只执行 一功能,不知道高级决策。
但是代码仍然需要清理它的资源(因为如果它不这样做,它们就会泄漏) ,所以它只在 finally子句中这样做,确保发生 一直都是,无论是否抛出异常。
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 块始终执行。