3.Try-with-resources in Java 7

try..with..resources是java7的一种新的异常处理机制,能够很容易的使用try…catch块正确关闭资源回收.

对于有资源回收管理的异常处理方式,老式学校的处理:

private static void printFile() throws IOException {
    InputStream input = null;

    try {
        input = new FileInputStream("file.txt");//1

        int data = input.read();//2
        while(data != -1){
            System.out.print((char) data);
            data = input.read();//3
        }
    } finally {
        if(input != null){
            input.close();//4
        }
    }
}

有4处地方容易发生异常,你可以看到,三处在try块,1处在finally块.finally块总是会执行,不管try块是否有异常抛出,这意味着, inputstream是会关闭的或者说试图关闭.
inputstream的close() 方法意味着也会抛出异常,如果关闭失败了. 想象一下异常从try块跑出来,finally块会执行.当异常冲finally块抛出的时候,这个异常会不会上抛给访问栈?
从finally块抛出的异常会传播给访问栈,即使try块的异常可能是更相关的传播。

try-with-resources
在java7你能写试用try-with-resource结构的代码来改造上面的案例:


private static void printFileJava7() throws IOException {

    try(FileInputStream input = new FileInputStream("file.txt")) {

        int data = input.read();
        while(data != -1){
            System.out.print((char) data);
            data = input.read();
        }
    }
}

注意第一行,这里的try-with-resources结构, 变量FileInputStream被声明在大括号里面,另外一FileInputStream是一个实例分配给一个变量.
当try块执行完成,FileInputStream将自动关闭.这是因为FileInputStream实现了java.lang.AutoCloseable接口.所有实现该接口的类都可以放在try-with-resources结构中.

如果一个异常从try-with-resources块中抛出,fileinputstream已经关闭了,try块中抛出的异常将抛到外层.异常会被抑制.这刚好和开头的案例相反(使用旧有异常处理).

使用多个资源
也可以使用try-with-resources块处理多个资源:

private static void printFileJava7() throws IOException {

    try(  FileInputStream     input         = new FileInputStream("file.txt");
          BufferedInputStream bufferedInput = new BufferedInputStream(input)
    ) {

        int data = bufferedInput.read();
        while(data != -1){
            System.out.print((char) data);
    data = bufferedInput.read();
        }
    }
}

这个案例创建了两个资源通过try关键字后面的括号. FileInputStream 和 BufferedInputStream.两个资源都会在执行流离开try块后自动关闭.
资源会通过反向初始化顺序的关闭, BufferedInputStream 先关闭, FileInputStream后关闭.

自定义可关闭资源的实现
使用try-with-resources结构不仅仅适用于java内建类.也能通过实现java.lang.autocloseable接口实现自己类使用.
下面是AutoCloseable接口:


public interface AutoClosable {

    public void close() throws Exception;
}

public class MyAutoClosable implements AutoCloseable {

    public void doIt() {
        System.out.println("MyAutoClosable doing it!");
    }

    @Override
    public void close() throws Exception {
        System.out.println("MyAutoClosable closed!");
    }
}

private static void myAutoClosable() throws Exception {

    try(MyAutoClosable myAutoClosable = new MyAutoClosable()){
        myAutoClosable.doIt();
    }
}

//console output
MyAutoClosable doing it!
MyAutoClosable closed!

你可以看到,try-with-resources是一个十分强大的方式确保使用在try-catch中的资源能正常关闭,不管这个资源时自己创建的还是java自带的组件.
译者:如果用户在使用一个类似于事务处理的业务时,可以通过实现该接口,完成一致性处理.

你可能感兴趣的:(翻译文章,java,exception)