简介

try-with-resourcesJava SE 7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源。资源是指程序执行完成后必须关闭的对象。try-with-resources语句确保每个资源在语句结束时关闭,任何实现java.lang.AutoCloseable的对象(包含所有实现java.io.Closeable的对象)都可以用作资源。

用法

示例

以下示例中使用BufferedReader从文件读取字符,BufferedReader就是一个程序执行完成后必须关闭的资源:

static String readFirstLineFromFile(String path) throws IOException {
    try (BufferedReader br =
                   new BufferedReader(new FileReader(path))) {
        return br.readLine();
    }
}

在上述例子中,在try-with-resources语句中声明的资源是BufferedReader, 声明语句出现在try之后的括号内。 Java SE 7及更高版本中的BufferedReader实现了java.lang.AutoCloseable接口。 由于BufferedReader实例是在try-with-resource语句中声明的,因此无论try语句是正常还是抛出异常,它都将被关闭。

Java SE 7之前,无论try语句是正常还是抛出异常,都需要手动使用finally来关闭资源,以下是一个常见的例子:

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
    BufferedReader br = new BufferedReader(new FileReader(path));
    try {
        return br.readLine();
    } finally {
        if (br != null) {
            br.close();
        }
    }
}

使用多个资源

try-with-resources语句中使用多个资源:

static void copyFile(File targetFile, File sourceFile) throws IOException {
        try (FileInputStream inputStream = new FileInputStream(targetFile);
            FileOutputStream outputStream = new FileOutputStream(sourceFile)) {
            byte[] bytes = new byte[1024];
            int length;
            while ((length = inputStream.read(bytes)) != -1) {
                outputStream.write(bytes, 0, length);
            }
        }
    }

上述例子中,在try中创建了两个资源FileInputStreamFileOutputStream;当程序执行完成或抛出异常终止时,FileInputStreamFileOutputStream将按照它们创建的顺序逆序关闭,即FileOutputStream先被关闭,然后才到FileInputStream被关闭。

自定义实现AutoCloseable

定义资源类

上述简介已说明所有实现java.lang.AutoCloseable接口(包括实现java.io.Closeable的所有对象),可以使用作为资源。因此我们创建类,实现AutoCloseable接口:

public class MyResource implements AutoCloseable {

    public void doRun() {
        System.out.println("MyResource run.");
    }

    @Override
    public void close() throws Exception {
        System.out.println("MyResource closed.");
    }
}

运行查看效果

public static void main(String[] args) throws Exception {
        try (MyResource resource  = new MyResource()) {
            resource.doRun();
        }
    }

从下图可看到,MyResource执行doRun()后就被关闭了。

auto-closeable-run-result.png

注意:try-with-resources语句可以像普通的try语句一样具有catchfinally块。 在try-with-resources语句中,声明的资源关闭后,将运行catchfinally块。

参考

https://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html

文章目录