跳至主要內容

04. Java带资源的捕获

LiuSongLing大约 2 分钟javajavaexception

对try-with-resources的支持——在Java 7中引入——允许我们声明在try块中使用的资源,并保证资源在执行该块后将被关闭。

声明的资源需要实现AutoCloseable接口。

1.使用try声明资源

要自动关闭,必须在try中声明资源:

try (PrintWriter writer = new PrintWriter(new File("test.txt"))) {
    writer.println("Hello World");
}

2.try-with-resources取代try-catch-finally

使用新的try-with-resources功能的简单而明显的方法是替换传统的verbostry-catch-finally块。

让我们比较以下代码示例。

第一个是典型的try-catch-finally块:

Scanner scanner = null;
try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

以下是使用try-with-resources的新的超级简洁解决方案:

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}





3.try-with-resources多种资源

我们可以通过用分号分隔多个资源,在try-with-resources块中声明多个资源:

try (Scanner scanner = new Scanner(new File("testRead.txt"));
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
    while (scanner.hasNext()) {
	writer.print(scanner.nextLine());
    }
}

4.带有自动关闭的自定义资源

要构建由try-with-resources块正确处理的自定义资源,该类应实现Closeable或AutoCloseable接口,并覆盖close方法:

public class MyResource implements AutoCloseable {
    @Override
    public void close() throws Exception {
        System.out.println("Closed MyResource");
    }
}

5.有效的最终变量

在Java 9之前,我们只能在try-with-resources块中使用新的变量:

try (Scanner scanner = new Scanner(new File("testRead.txt")); 
    PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) { 
    // omitted
}

如上所示,在声明多个资源时,这尤其冗长。从Java 9开始,作为JEP 213的一部分,我们现在可以在try-with-resources块中使用最终甚至有效的最终变量:

final Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))
try (scanner;writer) { 
    // omitted
}

简而言之,如果变量在第一次赋值后没有改变,即使它没有明确标记为最终,它实际上就是最终变量。

如上所示,scanner 变量被明确声明为final,因此我们可以将其与try-with-resources块一起使用。

虽然写入变量不是明确的最终变量,但在第一次分配后它不会改变。因此,我们也可以使用writer变量。