Java 7 中引入了 try-with-resources
特性来保证资源使用完毕后,自动进行关闭。任何实现了 java.lang.AutoCloseable
接口的类,都可以看作是资源,也都可以使用该特性。本文将详细介绍该特性的使用方法与注意事项。
1 传统的 try-finally 手动资源关闭
Java 7 之前,资源使用完毕后,需要在 finally
块中手动对其进行关闭。
看一段代码:
// src/test/java/TryWithResourcesTest#testJava6ReadFileWithFinallyBlock
@Test
public void testJava6ReadFileWithFinallyBlock() throws IOException {
String filePath = this.getClass().getResource("test.txt").getPath();
FileReader fr = null;
BufferedReader br = null;
try {
fr = new FileReader(filePath);
br = new BufferedReader(fr);
System.out.println(br.readLine());
} finally {
if (null != fr) {
fr.close();
}
if (null != br) {
br.close();
}
}
}
可以看到,如上测试用例尝试从 resources
文件夹下的文件 test.txt
里读取一行内容。用到了 FileReader
与 BufferedReader
文件流类,使用完毕后,在 finally
块内进行了关闭操作。
2 传统的 try-finally 手动资源关闭存在的问题
上面演示的这种在 try-finally
块进行资源使用及手动关闭的方式存在几个问题:
- 容易忘记关闭资源,从而引发内存泄漏;
- 资源比较多的时候,代码嵌套层次较深,代码可读性不佳;
- try 块与 finally 块同时发生异常时,存在异常压制问题。
下面就对这几个问题进行一一说明。
容易忘记关闭资源,从而引发内存泄漏
把资源关闭的事情交给开发人员自己手动处理的话,就容易发生忘记的情形。一旦忘记关闭,资源就会一直被认为在引用,垃圾收集器就无法对其进行回收,最终可能会引发内存泄漏问题。
资源比较多的时候,代码嵌套层次较深,代码可读性不佳</