try-with-resources机制

深入学习Java基础知识
2021-05-17 14:29 · 阅读时长4分钟
小课

try-with-resources机制是Java 7新增的语法,它可以实现在try代码块结束后自动释放声明的资源,能够降低代码量,提高代码可读性,使用方式如下

1import java.io.BufferedInputStream;
2import java.io.FileInputStream;
3import java.io.IOException;
4
5public class Main {
6
7    public static void main(String[] args) {
8        tryWithResource();
9        tryFinally();
10    }
11
12    public static void tryWithResource() {
13        /**
14         * 如果有需要可以在 try(..) 内部定义多个资源,使用分号隔开
15         * 例如: try(InputStream is1 = ...; InputStream is2 = ...;)
16         * 另外 try-with-resources 和普通 try 一样也可以定义 finally
17         */
18        try (BufferedInputStream input = new BufferedInputStream(new FileInputStream("/etc/hosts"))) {
19            System.out.println(new String(input.readAllBytes()));
20        } catch (Exception e) {
21            e.printStackTrace();
22        } finally {
23            System.out.println("finish");
24        }
25    }
26
27    /**
28     * try..finally 手动关闭资源
29     */
30    public static void tryFinally() {
31        BufferedInputStream input = null;
32        try {
33            input = new BufferedInputStream(new FileInputStream("/etc/hosts"));
34            System.out.println(new String(input.readAllBytes()));
35        } catch (Exception e) {
36            e.printStackTrace();
37        } finally {
38            if (input != null) {
39                try {
40                    input.close();
41                } catch (IOException e) {
42                    e.printStackTrace();
43                }
44            }
45        }
46    }
47}
48
注意: 这个Java运行环境不支持自定义包名,并且public class name必须是Main

其实在使用try-with-resources之后,编译器在编译时,会自动对代码加一层try...catch,并且调用资源类的close方法,所以资源类需要实现AutoCloseable接口,我们自定义一个类测试一下。

如果有多个资源类,先在try(..)中定义的资源类后调用关闭。

注释
1class CustomResource implements AutoCloseable {
2    private String name;
3
4    public CustomResource(String name) {
5        this.name = name;
6    }
7
8    @Override
9    public void close() {
10        System.out.println("close " + name);
11    }
12}
13
14public class Main {
15
16    public static void main(String[] args) {
17        /**
18         * 在Java9之后,资源类的定义可以放在外部
19         */
20        CustomResource resource1 = new CustomResource("resource1");
21        CustomResource resource2 = new CustomResource("resource2");
22        try (resource1; resource2) {
23            System.out.println("progress");
24        } catch (Exception e) {
25            e.printStackTrace();
26        } finally {
27            System.out.println("finish");
28        }
29    }
30}
31
注意: 这个Java运行环境不支持自定义包名,并且public class name必须是Main
try-with-resourcesjava