其他分享
首页 > 其他分享> > effective解读-第九条 try-with-resource代替try-fanilly释放资源

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)

 

标签:Demo2,fanilly,resource,java,try,new,close,out
来源: https://www.cnblogs.com/chengxuyuan-liu/p/14591314.html