大数据

try-with-resources 和 multi-catch

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,如下: