zoukankan      html  css  js  c++  java
  • effective解读-第九条 try-with-resource代替try-fanilly释放资源

    做java的都知道,有写资源使用完毕后要及时的释放否则会导致OOM,例如流资源,我们一般放在finally中进行释放(确保流资源一定被释放)

    try-finally的缺点有两个,使用try-with-resources完美解决

    1. AutoCloseable接口的close本身就会抛出异常,所以如果同时关闭多个异常的话就会使代码显得非常臃肿

    //例如POIUtils工具类中的代码
    try {
        out = response.getOutputStream();
        workbook = new XSSFWorkbook(byteArrayInputStream);
        workbook.write(out);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
        throw new AppException();
    } finally {
        try {
            byteArrayInputStream.close();
        } catch (IOException e) {
            log.error("关闭流异常", e);
        }
        try {
            if (out != null) {
                out.close();
            }
        } catch (IOException e) {
            log.error("关闭流异常", e);
        }
        try {
            if (workbook != null) {
                workbook.close();
            }
        } catch (IOException e) {
            log.error("关闭流异常", e);
        }
    }
    //改进后的版本
    try (
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data);
        OutputStream out = response.getOutputStream();
        Workbook workbook = new XSSFWorkbook(byteArrayInputStream);
    ) {
        workbook.write(out);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
        throw new AppException();
    }

    2. try中和finally中都有异常堆栈只会保留后面的异常,导致起那面的异常难以排查

    public class Demo2 {
        private static class TestDemo implements AutoCloseable{
            @Override
            public void close(){
                throw new RuntimeException();
            }
        }
    
        public static void main(String[] args) {
            TestDemo testDemo = null;
            try{
                testDemo = new TestDemo();
                //异常
                int i = 1 / 0;
            }finally {
                testDemo.close();
            }
        }
    }
    //运行结果,只能看到finally里面的异常,而忽略了业务中的异常
    Exception in thread "main" java.lang.RuntimeException
        at infosecuritydemo.demo.optional.Demo2$TestDemo.close(Demo2.java:11)
        at infosecuritydemo.demo.optional.Demo2.main(Demo2.java:21)
    //改进后的版本
    public static void main(String[] args) {
        try (TestDemo testDemo = new TestDemo()) {
            int i = 1 / 0;
        }
    }
    //运行后异常明显的打印出来
    Exception in thread "main" java.lang.ArithmeticException: / by zero
        at infosecuritydemo.demo.optional.Demo2.main(Demo2.java:20)
          //会自动调用Throwable的getSuppressed()方法为我们打印出被隐藏的异常
        Suppressed: java.lang.RuntimeException
            at infosecuritydemo.demo.optional.Demo2$TestDemo.close(Demo2.java:14)
            at infosecuritydemo.demo.optional.Demo2.main(Demo2.java:21)
    作者:刘志红

    -------------------------------------------

    个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!

    如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!

  • 相关阅读:
    Express 框架以及与http-proxy-middleware整合实现代理
    Ajax跨域问题
    XStream处理XML用法
    vue中引入mintui、vux重构简单的APP项目
    vue-cli安装以及创建一个简单的项目(二)(vuex使用、发行一个简单的app)
    JS实现图片懒加载
    ECMAScript 6.0 简要学习
    【Android】自定义控件让TextView的drawableLeft与文本一起居中显示
    【Android】不使用WebView来执行Javascript脚本(Rhino)
    【Android】Fragment真正意义上的onResume和onPause
  • 原文地址:https://www.cnblogs.com/chengxuyuan-liu/p/14591314.html
Copyright © 2011-2022 走看看