try-with-resources 优雅关闭资源

参考链接:Java7的try-with-resources声明

1.案例说明:

public static void main(String[] args) {
    // 配置规则.
    initFlowRules();

    while (true) {
        // 1.5.0 版本开始可以直接利用 try-with-resources 特性,自动 exit entry
        try (Entry entry = SphU.entry("HelloWorld")) {
            // 被保护的逻辑
            System.out.println("hello world");
	} catch (BlockException ex) {
            // 处理被流控的逻辑
	    System.out.println("blocked!");
	}
    }
}

2. 用法辨析

Java库中有很多资源需要手动关闭,比如InputStream、OutputStream、java.sql.Connection等等。在此之前,通常是使用try-finally的方式关闭资源;Java7之后,推出了try-with-resources声明来替代之前的方式。 try-with-resources 声明要求其中定义的变量实现 AutoCloseable 接口,这样系统可以自动调用它们的close方法,从而替代了finally中关闭资源的功能。

2.1 try-catch-finally 写法

// 一个简单的复制文件方法。
public static void copy(String src, String dst) {
    InputStream in = null;
    OutputStream out = null;
    try {
        in = new FileInputStream(src);
        out = new FileOutputStream(dst);
        byte[] buff = new byte[1024];
        int n;
        while ((n = in.read(buff)) >= 0) {
            out.write(buff, 0, n);
        }
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (out != null) {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

2.2 try-with-resources 写法

public static void copy(String src, String dst) {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buff = new byte[1024];
        int n;
        while ((n = in.read(buff)) >= 0) {
            out.write(buff, 0, n);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}
  • try-with-resources将会自动关闭try()中的资源,并且将先关闭后声明的资源。
  • 如果不catch IOException就更加清爽了:
public static void copy(String src, String dst) throws IOException {
    try (InputStream in = new FileInputStream(src);
         OutputStream out = new FileOutputStream(dst)) {
        byte[] buff = new byte[1024];
        int n;
        while ((n = in.read(buff)) >= 0) {
            out.write(buff, 0, n);
        }
    }
}

3. 原理分析 

  •  那么try-with-resources有什么神奇之处呢?到底做了什么呢?

  •  我们先来看下AutoCloseable接口:

public interface AutoCloseable {
    void close() throws Exception;
}

其中仅有一个close方法,实现AutoCloseable接口的类将在close方法中实现其关闭资源的功能。
而try-with-resources其实是个语法糖,它将在编译时编译成关闭资源的代码。
我们将上述例子中的代码编译成class文件,再反编译回java文件,就能看到如下代码:

public static void copy(String var0, String var1) throws IOException {
    FileInputStream var2 = new FileInputStream(var0);
    Throwable var3 = null;

    try {
        FileOutputStream var4 = new FileOutputStream(var1);
        Throwable var5 = null;

        try {
            byte[] var6 = new byte[1024];

            int var7;
            while((var7 = var2.read(var6)) >= 0) {
                var4.write(var6, 0, var7);
            }
        } catch (Throwable var29) {
            var5 = var29;
            throw var29;
        } finally {
            if (var4 != null) {
                if (var5 != null) {
                    try {
                        // 关闭FileOutputStream
                        var4.close();
                    } catch (Throwable var28) {
                        var5.addSuppressed(var28);
                    }
                } else {
                    var4.close();
                }
            }

        }
    } catch (Throwable var31) {
        var3 = var31;
        throw var31;
    } finally {
        if (var2 != null) {
            if (var3 != null) {
                try {
                    // 关闭FileInputStream
                    var2.close();
                } catch (Throwable var27) {
                    var3.addSuppressed(var27);
                }
            } else {
                var2.close();
            }
        }

    }

}

除却处理异常相关的代码,其实就是调用了资源的close方法。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值