java炒冷饭系列08 try-with-resources

来源:互联网 发布:如何自学成为程序员 编辑:程序博客网 时间:2024/06/03 13:07

前言

这次的米饭不太冷,前几篇文章聊了聊java的异常体系,就想起来了java7中新增加的try-with-resources语句,其实我也不熟悉,大家一起来看看吧

介绍

try-with-resources语句是声明一个或多个资源的try语句

try-with-resources语句是声明一个或多个资源的try语句。一个资源作为一个对象,必须在程序结束之后随之关闭。try-with-resources语句确保在语句的最后每个资源都被关闭。任何实现了java.lang.AutoCloseable的对象,包括所有实现了java.io.Closable的对象,都可以用作一个资源

下面的例子读取文件的第一行。它使用了BufferedReader的一个实例来读取文件中的数据。BufferedReader是一个资源,它必须在程序结束之后随之关闭:

    public static String readFirstLineFromFile(String path) throws IOException {        try (BufferedReader br = new BufferedReader(new FileReader(path))) {            return br.readLine();        }    }

在这个例子中,try-with-resources语句声明的资源是一个BufferedReader。声明语句在紧跟在try关键字的括号里面。Java SE 7 以及后续版本中,BufferedReader类实现了java.lang.AutoCloseable接口。因为BufferedReader实例是在try-with-resource语句中声明的,所以不管try语句正常地完成或是发生意外(结果就是BufferedReader.readLine方法抛出IOException),BufferedReader都将会关闭

在Java SE 7 之前,可以使用finally块来确保资源被关闭,不管try语句正常地完成或是发生意外。下面的例子使用finally块替换try-with-resources语句:

public static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {        BufferedReader br = null;        try{            br = new BufferedReader(new FileReader(path));            return br.readLine();        }finally {            if (br != null) {                br.close();            }        }    }

然则,在这个例子中,如果readLine和close方法均抛出异常,那么readFirstLineFromFileWithFinallyBlock方将抛出从finaly块中抛出的异常, try块中抛出的异常被抑制了。

与此相反,在readFirstLineFromFile这个例子中,如果try块和try-with-resources语句均抛出异常,那么readFirstLineFromFile将抛出从try块中抛出的异常;try-with-resources块抛出的异常被抑制了

空口无评,上代码验证

public class MyCloseable implements Closeable {    @Override    public void close() throws IOException {        throw new IOException("MyCloseable.close() throw the exception");    }    //try-finally    public static void tryFinally() throws IOException {        MyCloseable myCloseable = null;        try{            myCloseable = new MyCloseable();            throw new IOException("in the try finally statement");        }finally {            if (myCloseable != null) {                myCloseable.close();            }        }    }    //try-with-resources    public static void tryWith() throws IOException {        try (MyCloseable myCloseable = new MyCloseable()) {            throw new IOException("in the try statement");        }    }    public static void main(String[] args) throws IOException {        tryFinally();    }}

输出如下

//try-finallyException in thread "main" java.io.IOException: MyCloseable.close() throw the exception    at com.jianglei.p12.cmy_11.MyCloseable.close(MyCloseable.java:12)    at com.jianglei.p12.cmy_11.MyCloseable.tryFinally(MyCloseable.java:22)    at com.jianglei.p12.cmy_11.MyCloseable.main(MyCloseable.java:35)//try-with-resourcesException in thread "main" java.io.IOException: in the try statement    at com.jianglei.p12.cmy_11.MyCloseable.tryWith(MyCloseable.java:29)    at com.jianglei.p12.cmy_11.MyCloseable.main(MyCloseable.java:36)    Suppressed: java.io.IOException: MyCloseable.close() throw the exception        at com.jianglei.p12.cmy_11.MyCloseable.close(MyCloseable.java:12)        at com.jianglei.p12.cmy_11.MyCloseable.tryWith(MyCloseable.java:30)        ... 1 more

可以在一个try-with-resources语句中声明一个或多个资源。

可以在一个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会被关闭

自定义AutoClosable实现

这个try-with-resources结构里不仅能够操作java内置的类。你也可以在自己的类中实现java.lang.AutoCloseable接口,然后在try-with-resources结构里使用这个类

参考文献

Java 7中的Try-with-resources:http://ifeve.com/java-7%E4%B8%AD%E7%9A%84try-with-resources/
Java SE7新特性之try-with-resources语句:http://blog.csdn.net/jackiehff/article/details/17765909