陷阱忘记了免费资源
每次程序打开资源(例如文件或网络连接)时,一旦使用完资源,释放资源非常重要。如果在对此类资源的操作期间抛出任何异常,则应采取类似的谨慎措施。有人可能会说, FileInputStream
有一个终结器 ,可以在垃圾收集事件中调用 close()
方法; 但是,由于我们无法确定垃圾收集周期何时开始,因此输入流可以无限期地消耗计算机资源。必须在 try-catch 块的 finally
部分中关闭资源:
Version < Java SE 7
private static void printFileJava6() throws IOException {
FileInputStream input;
try {
input = new FileInputStream("file.txt");
int data = input.read();
while (data != -1){
System.out.print((char) data);
data = input.read();
}
} finally {
if (input != null) {
input.close();
}
}
}
从 Java 7 开始,Java 7 中引入了一个非常有用且简洁的语句,特别是针对这种情况,称为 try-with-resources:
Version >= Java SE 7
private static void printFileJava7() throws IOException {
try (FileInputStream input = new FileInputStream("file.txt")) {
int data = input.read();
while (data != -1){
System.out.print((char) data);
data = input.read();
}
}
}
在试穿与资源语句可以使用实现 Closeable
或 AutoCloseable
接口的任何对象使用。它确保在语句结束时关闭每个资源。两个界面之间的区别在于,Closeable
的 close()
方法抛出了一个必须以某种方式处理的 IOException
。
如果资源已经打开但应该在使用后安全关闭,可以将其分配给 try-with-resources 中的局部变量
Version >= Java SE 7
private static void printFileJava7(InputStream extResource) throws IOException {
try (InputStream input = extResource) {
... //access resource
}
}
在 try-with-resources 构造函数中创建的本地资源变量实际上是最终的。