finally代码块在try代码块退出后一定会执行。这保证了无论有没有发生异常,finally代码块总是会执行。可是finally的用处可不止于处理异常——它允许程序员避免发生这样的意外,因一个return、continue或者break语句绕过了代码清理语句。在finally代码块中放置代码清理语句是一个很好的实践,即使没有任何可预期的异常。

备注:当执行try或catch代码的时候,JVM退出了,finally代码块可能不会执行。同样,如果执行try或catch代码的线程被中断或杀死,即使整个应用还在运行,finally代码块也不会再执行。

在writeList方法的try代码块里面打开了一个PrintWriter。程序应该在退出writeList方法之前关闭这个流。这造成了一个稍微比较复杂的问题,因为writeList的try代码块可能以以下三种方式退出:
  1. new FileWriter语句失败并抛出一个IOException
  2. list.get(i)语句失败并抛出一个IndexOutOfBoundsException
  3. 一切正常

运行时系统始终会执行finally代码块,不管try代码块里发生了什么。所以这是一个执行清理的理想地。

下面的代码展示了在writeList方法的finally代码块执行清理,关闭PrintWriter:

finally {
    if (out != null) {
        System.out.println("Closing PrintWriter");
        out.close();
    } else {
        System.out.println("PrintWriter not open");
    }
}


重要:finally代码块是防止资源泄露的关键工具。当关闭文件或恢复资源,将这些代码放到finally代码块中就可以保证资源总可以恢复。

这种情形可以考虑用try-with-resources语句,它可以自动释放系统资源,当这些资源不再需要使用的时候。参看 The try-with-resources Statement 有更多相关信息。





原文地址