陷阱忘记了免费资源

每次程序打开资源(例如文件或网络连接)时,一旦使用完资源,释放资源非常重要。如果在对此类资源的操作期间抛出任何异常,则应采取类似的谨慎措施。有人可能会说, 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();
        }
    }
}

试穿与资源语句可以使用实现 CloseableAutoCloseable 接口的任何对象使用。它确保在语句结束时关闭每个资源。两个界面之间的区别在于,Closeableclose() 方法抛出了一个必须以某种方式处理的 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 构造函数中创建的本地资源变量实际上是最终的。