try-with-resources 和 multi-catch

作者: littlersmall | 来源:发表于2016-08-11 15:44 被阅读337次

    java7里新增的内容。

    1 try-with-resources
    比如这样的情况:
    需要从一个文件里读出所有内容。代码如下:

    public static void readAll() throws IOException {
        FileReader fileReader = new FileReader("test");
        BufferedReader bufferedReader = new BufferedReader(fileReader);
    
        String line;
    
        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
    
        fileReader.close();
        bufferedReader.close();
    }
    

    如果我们不希望在函数接口中抛出异常,需要自己做try,catch处理。大概是这样的:

    public static void readAll() {
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
            
        try {
            fileReader = new FileReader("test");
            bufferedReader = new BufferedReader(fileReader);
    
            String line;
    
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
                
            fileReader.close();
            bufferedReader.close();           
        } catch (IOException e) {
            e.printStackTrace();
        } 
    }
    

    但是这种方式并不是很好,因为在中间的bufferedReader.readLine()处也可能抛出异常,造成fileReader和bufferedReader无法关闭。因此更安全的方式是在finally中关闭文件,类似这样:

    try {
     ...
    } catch(...) {
    } finally {
        file.close();    
    }
    

    但是,file.close()也会抛出异常,所以最终的安全代码如下:

    public static void readAll() {
        FileReader fileReader = null;
        BufferedReader bufferedReader = null;
    
        try {
            fileReader = new FileReader("test");
            bufferedReader = new BufferedReader(fileReader);
    
            String line;
    
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
    
            fileReader.close();
            bufferedReader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileReader != null) {
                try {
                    fileReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
    
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    这样写是没有问题了,但是过于繁琐,将原本很清晰简单的逻辑无端的复杂化了。为了解决这个问题,java引入了类似python with的方式,try-with-resources,我们使用try-with-resources的方式改写这段代码如下:

    public static void readAll() {
        try (
            FileReader fileReader = new FileReader("test");
            BufferedReader bufferedReader = new BufferedReader(fileReader)
        ) {
            String line;
    
            while ((line = bufferedReader.readLine()) != null) {
                System.out.println(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    

    由java从语言层面保证fileReader和bufferedReader一定关闭,代码也非常简洁清晰。
    如果需要使用try-catch-resource,需要保证你的资源实现了:

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

    2 multi-catch
    正常的try,catch多个异常如下:

    public static void multiCatch() {
        try {
            if (System.currentTimeMillis() % 2 == 0) {
                throw new IOException();
            } else {
                throw new ClassNotFoundException();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    

    两种异常的处理逻辑大致相同,因此可以使用multi-catch,将代码简化为:

    public static void multiCatch() {
        try {
            if (System.currentTimeMillis() % 2 == 0) {
                throw new IOException();
            } else {
                throw new ClassNotFoundException();
            }
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    

    注意:multi-catch语法时的异常不能有相交。如IOException是Exception的子类, 所以以后用 | 分隔开的异常不能有父子关系。例如:
    catch (IOException | Exception e) 将报错。

    3 开启编译支持。
    为了使用java7和8的新特性,建议将maven-compiler-plugin的configuration修改为1.8,如下:


    相关文章

      网友评论

        本文标题:try-with-resources 和 multi-catch

        本文链接:https://www.haomeiwen.com/subject/lbrjsttx.html