• 解决多个io流需要关闭而重复嵌套try-catch-finally的问题


    问题如图:

    相信大多数人都见过如此状态,流多了需要层层关闭,需要层层加上try-catch,为保证下一个流能关闭又要加上finally,烦人!!

    我们先来一个测试:

    public class Test {
        public static void main(String[] args) {
            try {
                System.out.println("第一try");
                throw new Exception("异常");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                System.out.println("finally");
                try {
                    throw new Exception("又是异常");
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                System.out.println("会执行吗");
            }
        }
    }

    运行结果:

    提取出重要信息,finally里面可以抓到异常后可以继续往下执行,也就是说finally里面try-catch抓到异常后也必须把这个代码块执行完。

    那么有人就写了一个工具类,这种工具类对吗?

    
    public class IOUtil {
        public static void close(Closeable... closeableList) {
            try {
                for (Closeable closeable : closeableList) {
                    if (closeable != null){
                        closeable.close();
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    然后

    finally{
          IOUtil.close(is, os);
    }

    看似正确,实则错误!!

    如果第一个流关闭的时候异常,那么第二个流close()就不可达,执行不到

    这和并列写没区别,如下:

    finally{

        try{

              is.close();

              os.close();   // 第一个流关闭出异常第二个流关闭就不可达,执行不到,等于没关

        } catch(Exception e) {

        }

    }

    那怎么办呢?不能写工具类吗?

    不是不能写,而是这种写法是错误的,这种情况下应该把try-catch放在for循环里面,这样才能保证循环会依次关闭流

    正确写法1:

    public static void close(Closeable... closeableList) {
        for (Closeable closeable : closeableList) {
            try {
                if (closeable != null) {
                    closeable.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    然后

    finally{
          IOUtil.close(is, os);
    }

    正确解法2:

    public <T extends java.io.Closeable> void close(T t) {
        try {
            if (t != null) {
                t.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    然后

    finally {
        close(in);
        close(raf);
        close(br);
    }

    哪怕其中有流关闭出了异常,也不会影响到其他流的关闭,finally{...}里面的东西是要执行完的

    =============================Talk is cheap, show me the code===========================

    CSDN博客地址:https://blog.csdn.net/qq_34115899
  • 相关阅读:
    Java消息队列-Spring整合ActiveMq
    控制 Memory 和 CPU 资源的使用
    真的了解js生成随机数吗
    vue原来可以这样上手
    Weex系列一、构建Weex工程
    MS Word 目录排版
    mac上使用终端编译omp代码
    x的平方根
    如何进行特征选择
    单词模式
  • 原文地址:https://www.cnblogs.com/lcy0515/p/10807875.html
Copyright © 2020-2023  润新知