Java抛出异常机制中的Finally的作用
一直不知道Java中Finally的作用,因为总感觉没有什么用,事实上,当初学Javascript时也有同样的疑问,后来Google下,才明白过来。
public void writeFile(String filePath, String fileName, String args) throws IOException { FileWriter fw = new FileWriter(filePath + fileName); try { fw.write(args); } catch (IOException e) { //1 fw.close(); throw e; } //2 fw.close(); }
这段代码创建了一个FileWriter object,并调用 write 方法。在退出该方法之前,您必须关闭FileWriter object,以避免资源漏洞。为了完成这一任务,我们在 //2 处调用 close,它是该方法的最后一条语句。但是,如果 try 块中发生一个异常会怎么样呢?在这种情况下,//2 处的 close 调用永远不会发生。因此,您必须捕获这个异常,并在重新发出这个异常之前在 //1 处插入对 close 的另一个调用。这样就可以确保在退出该方法之前关闭FileWriter object。这样编写代码既麻烦又易于出错,但在没有 finally 的情况下这是必不可少的。有了 finally,前面的代码就可以重写为以下的形式:finally 关键字是对 Java 异常处理模型的最佳补充。 finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源。如果没有 finally,您的代码就会很费解。例如,下面的代码说明,在不使用 finally 的情况下您如何编写代码来释放非内存资源:
public void writeFile(String filePath, String fileName, String args) throws IOException { FileWriter fw = new FileWriter(filePath + fileName); try { fw.write(args); } catch (IOException e) { throw e; } finally { fw.close(); } }
finally 块确保 close 方法总被执行,而不管 try 块内是否发出异常(或是try块中有突如其来的return)。因此,可以确保在退出该方法之前总会调用 close 方法。这样您就可以确信FileWriter object被关闭并且您没有泄漏资源。
参考文献:
对于一些无可奈何的二元操作(神马是二元操作?二元操作是指当调用一个函数后必须成对调用另一个函数,这两个函数总是成对使用,否则可能会导致严重错误。比如文件的打开和关闭,加锁和释放锁。二元操作本身不是难点,但是人们非常容易忘记调用第二个函数,从而造成隐患,这在一个代码块中有多个如return,break,continue之类跳转语句时极易发生,以前有本书希望我们永远在代码块中只设定一个出口,但是这么做难度很大),由于Java的析构函数总不是很给力(无法确定何时调用,是否会调用,不能用它来包装第二个操作,这和C++完全不一样),我们完全可以使用Finally来完成第二个操作,这样就不会遗忘了。我们只要让第一个操作的那个代码块被try包围,第二个操作写在之后的finally中,catch可以不需要,这样无论接下来有多少个可能导致跳出代码块的语句,第二次操作总会被执行,毋须任何担忧。