The try-with-resources Statement

本文转自这里
try-with-resources也是一种try语句,只不过额外声明了一个或多个必须在程序结束时必须关闭的资源。try-with-resources确保这些资源在程序结束时被关闭,资源是任何实现了java.lang.AutoCloseable接口的对象,或者任何实现了java.io.Closeable接口的对象(因为间接实现了java.lang.AutoCloseable)。
以下代码读取文件中的第一行,它用BufferedReader来读文件,BufferedReader就是程序结束时必须关闭的资源。

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

这个例子中,BufferedReader就是声明在try-with-resources中的资源,声明语句包含在圆括号中,紧跟try关键字。BufferedReader在java SE 7后实现了java.lang.AutoCloseable接口,因为在try-with-resources中被声明了,因此不管br.readLine()有无抛出IOException,它都会正常关闭。
在java SE 7之前的版本,可以用finally达到同样的效果。以下代码使用finally而不是try-with-resources

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

但是,在上述例子中,readline()和close()都抛了异常,而外部方法readFirstLineFromFileWithFinallyBlock() 抛的是finally块的异常,try块的异常被抑制了。相比之下,readFirstLineFromFile方法,如果try块和try-with-resources块都有异常抛出,readFirstLineFromFile最终抛的是try块的异常,而try-with-resources的异常被抑制了。Java SE 7之后,可以通过方法获取到被抑制的异常。
try-with-resources可以定义多个资源:

public static void writeToFileZipFileContents(String zipFileName,
                                           String outputFileName)
                                           throws java.io.IOException {

    java.nio.charset.Charset charset =
         java.nio.charset.StandardCharsets.US_ASCII;
    java.nio.file.Path outputFilePath =
         java.nio.file.Paths.get(outputFileName);

    // Open zip file and create output file with 
    // try-with-resources statement

    try (
        java.util.zip.ZipFile zf =
             new java.util.zip.ZipFile(zipFileName);
        java.io.BufferedWriter writer = 
            java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
    ) {
        // Enumerate each entry
        for (java.util.Enumeration entries =
                                zf.entries(); entries.hasMoreElements();) {
            // Get the entry name and write it to the output file
            String newLine = System.getProperty("line.separator");
            String zipEntryName =
                 ((java.util.zip.ZipEntry)entries.nextElement()).getName() +
                 newLine;
            writer.write(zipEntryName, 0, zipEntryName.length());
        }
    }
}

多个资源通过分号分割,它们的close方法会按照定义顺序的倒序被自动调用。
和普通try一样,try-with-resources语句可以有catchfinally块,任何catchfinally都在try-with-resources定义的资源关闭后执行。
try-with-resources语句中,如果try块抛出了一个异常,try-with-resources也抛出了异常,那么前者异常将被抛出,后者被抑制。可以通过Throwable.getSuppressed得到被抑制的异常。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值