try-with-resources语句

什么是try-with-resources语句

我们正常处理Java异常过程中使用的try代码块,一般都没有括号。在Java的体系中try的后面如果使用括号包含一些语句作为条件,我们把这样的try代码块就叫它【try-with-resources】语句。

try-with-resources语句是一个try语句,它声明一个或多个资源。资源是必须在程序使用完它以后必须被关闭的一个对象。try-with-resources语句确保每一个资源在代码块的执行完成后被关闭。任何实现了java.lang.AutoCloseable的对象,包含所有实现了java.io.Closeable的对象,都能够作为资源被使用。

下面的例子是从一个文件中读取第一行。它用一个FileReader和BufferedReader的实例从文件中读取数据。FileReader和BufferedReader都是需要在程序使用完它们以后必须被关闭的。我们使用Java SE7以前的try语句和Java SE7以后的try-with-resources两种方式实现上述操作,对比一下他们的不同。

JDK7以前

    public Test(){
        String filePath = "D:" + File.separator + "temp"
                + File.separator + "trywithresources.txt";
        FileReader fr = null;
        BufferedReader br = null;
        try{
            fr = new FileReader(filePath);
            br = new BufferedReader(fr);
            String firstLine = br.readLine();

            System.out.println(firstLine);

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //程序正常执行完成后,关闭FileReader和BufferedReader的两个对象
            try{
                fr.close();
                br.close();
            }catch (Exception e){
                e.printStackTrace();
            }
        }

        System.out.println(br + "   " + fr);
    }

在Java SE7以及以前,由于java.io.的相关类还没有实现java.lang.Closeable和java.lang.AutoCloseable接口,所以你能使用finally代码块来确认资源被关闭,无论try语句正常完成还是异常终止。

然而这种方式可能存在资源泄漏。程序不得不在使用完以后,更多的依赖GC来回收资源所占的内存。程序也必须释放资源返回给操作系统,通常通过调用资源的关闭方法。然而,如果程序在GC回收资源以前,调用关闭资源方法失败,那么需要释放资源的信息就会丢失,这些资源一直会被操作系统认为正在使用中,出现泄漏。

在上面的例子中,如果readLine方法抛出一个异常,并且在finally块中的br.close()语句抛出异常,那么FileReader有泄漏。

JDK7以后,使用try-with-resources

    public Test(){
        String filePath = "D:" + File.separator + "temp"
                + File.separator + "trywithresources.txt";

        try(
                FileReader fr = new FileReader(filePath);
                BufferedReader br = new BufferedReader(fr)
        ){
            String firstLine = br.readLine();
            System.out.println(firstLine);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

在这个例子中,被定义在try-with-resources语句中资源是FileReader和BufferedReader。定义这些资源的语句出现在try关键字后面的小括号里。在Java SE7及以上版本中,FileReader和BufferedReader这两个类都实现了java.lang.AutoCloseable。由于FileReader和BufferedReader这两个类的实例都是通过try-with-resources定义的,无论try语句是正常完成还是异常退出,他们都会被关闭。

留下评论

您的邮箱地址不会被公开。 必填项已用 * 标注