别再在finally里面释放资源了,解锁个新姿势!

227 阅读1分钟

整理了一份Java、JVM、多线程、MySQL、Redis、Kafka、Docker、RocketMQ、Nginx、MQ队列、数据结构、并发编程、并发压测、秒杀架构等技术知识点PDF,如果你有需要的话,可_click here_领取

在我们编码过程中,不可避免地会用到于文件操作 IO 流、数据库连接等开销比较大的资源,用完之后需要通过 close 方法将其关闭,否则资源一直处于打开状态,可能会导致内存泄露等问题。

拿文件操作流举例,我们在使用时要try catch,用完了在finally中关闭,而关闭的时候还需要在try catch,可以说是非常麻烦了!代码如下:

        /**传统写法**/
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(""));
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            // DO something
        } finally {
            if(br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    // DO something
                }
            }
        }

而我们的新姿势是使用JDK1.7中的try-with-resources语法,直接上代码:

        /**使用语法糖**/
        try (BufferedReader br1 = new BufferedReader(new FileReader(""))) {
            String line;
            while ((line = br1.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            // DO something
        }

代码是不是瞬间清爽了很多?赶紧用起来吧~

我们顺便再来刨根究底一下吧,看下他编译之后的样子:

        try {
            BufferedReader br1 = new BufferedReader(new FileReader(""));
            Throwable var7 = null;

            try {
                String line;
                try {
                    while((line = br1.readLine()) != null) {
                        System.out.println(line);
                    }
                } catch (Throwable var32) {
                    var7 = var32;
                    throw var32;
                }
            } finally {
                if (br1 != null) {
                    if (var7 != null) {
                        try {
                            br1.close();
                        } catch (Throwable var31) {
                            var7.addSuppressed(var31);
                        }
                    } else {
                        br1.close();
                    }
                }
            }
        } catch (IOException var34) {
        }

其实背后的原理也很简单,让编译器都帮我们做了关闭资源的工作而已。所以,再次印证了,语法糖的作用就是方便程序员的使用,最终还是要转成编译器认识的语言。