大白话之AutoClosable接口 | try-with-resources:JDK1.7的新特性,提高重复回收效率

前言

无论是使用文件IO流,还是网络Socket流,都免不了调用close()将流关闭。如果需要操作的流过多,就会导致混乱。
一旦忘记将关闭方法放到finally中,很有可能出现流未被关闭,占用大量内存空间的问题。

流程简化

对比

try-catch-finally

 1        AC ac = null;
 2        AC2 ac2 = null;
 3        try {
 4            ac = new AC();
 5            ac2 = new AC2();
 6        } catch (Exception e) {
 7        } finally {
 8            ac.close();
 9            ac2.close();
10        }

try-with-resources

1        try (AC ac = new AC();
2             AC2 ac2 = new AC2()) {
3        } catch (Exception e) {
4        }

可以很明显的看到,try-with-resources会自动调用类中的close()方法,简化了流程,提高了代码的整洁度。

AutoCloseable

AutoCloseable是Java的内置接口,继承这个接口并且按要求新建close()方法,该类就能被try-with-resources语法所支持。

示例

还记得我们刚才演示使用的两个类:ACAC2吗?它们的代码如下:

AC.java

 1public class AC implements AutoCloseable {
 2    @Override
 3    public void close() throws Exception {
 4        System.out.println("Program has been closed pretended.");
 5    }
 6
 7    //默认静态方法,在被实例化时执行
 8    static {
 9        System.out.println("Program running.");
10    }
11}

AC2.java

 1public class AC2 implements AutoCloseable {
 2    @Override
 3    public void close() throws Exception {
 4        System.out.println("Program 2 has been closed pretended.");
 5    }
 6
 7    static {
 8        System.out.println("Program 2 running.");
 9    }
10}

AC2AC在实现上是相同的。我创建两个类的原因是想让大家知道try-with-resources可以支持同时进行多个类的关闭。再编写一个主方法,运行测试:

Main.java

 1public class Main {
 2    public static void main(String[] args) {
 3        try (AC ac = new AC();
 4             AC2 ac2 = new AC2()) {
 5            //这里假装执行了有用的代码
 6            Thread.sleep(2000);
 7        } catch (Exception e) {
 8        }
 9    }
10}

测试

运行结果

1Program running.
2Program 2 running.
3(这里有2秒的延时)
4Program 2 has been closed pretended.
5Program has been closed pretended.

可以看到,try-with-resource对类进行了实例化,并且在代码执行完毕后进行了回收(调用了各个类的close()方法)。

后语

思考

仔细分析运行结果,你会发现该语法的运行规律是先进后出,后进先出AC2是最后被实例化的,但却是第一个被关闭了。

这种机制像什么?如果你对计算机原理有所研究的话,你会发现,堆栈就是先进后出的机制。

当然,由于try-with-resources是Java的“语法糖”,我的知识还无法追踪到它的源码(JVM)当中去。但我们可以基本确定,try-with-resources的实例化和回收机制,就是用类似堆栈的算法来实现的。

如转载请在文章尾部添加

原作者来自 adlered 个人技术博客:https://www.stackoverflow.wiki/

    评论
    2 评论
    2019-07-05 15:20 回复»

    对啊😂

    2019-07-05 13:34 回复»

    评论还得登录呢😰

avatar

取消