Java 1.7新特性之(try-with-resources)

前言:try语句的增强,增添了自动调用资源的close功能。(我在下文中将Statement翻译成声明,感觉不太合适,但又不知如何解释,有好的解释请大家留言!)

The try-with-resources Statement

  The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.

   try-with-resources这种声明方式指定了一个或多个资源,而且这些资源需要在程序结束的时候进行关闭。这种方式可以确保每个指定的资源都可以在声明结束的时候进行关闭(就是在try(){}结束的时候)。但是前提是这些资源必须实现接口java.lang.AutoCloseable(其中包括实现了java.io.Closeable接口的所有对象),原因是java.io.Closeable接口继承了java.lang.AutoCloseable接口。

   The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:

   下面示例中的第一行是从文件中读取数据。实例中使用的是BufferedReader的实例来从文件中读取数据的。BufferedReader是一个资源需要在程序结束的时候将其关闭:

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

   In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).
    在这个示例中,使用 try-with-resources声明的资源是BufferedReader。try-with-resources声明的方式是在try关键字之后紧跟着在括号中声明。BufferedReader这个类在Java SE 7 及以后的版本中实现了java.lang.AutoCloseable这个接口。由于BufferedReader的实例是生命在try-with-resource的声明中,所以无论try语句执行正常还是异常,都会被关闭掉(即使在bufferedreader.readline执行过程中抛出IOException异常)。

   Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:

    在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();
    }
}

   However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the section Suppressed Exceptions for more information.
    然而,在这个例子中,如果方法readLine与方法close都抛出异常,readFirstLineFromFileWithFinallyBlock从finally块中抛出异常,然而异常从try块中 抛出是受限制的。我们来比较一下这两个例子,在readFirstLineFromFile中,如果同时从try块与try-with-resources声明中抛出,从try块中的异常正常抛出,但是从try-with-resources块中抛出的异常被限制。在Java SE 7以及之后版本,我们可以获得受限制的异常;查看Suppressed Exceptions来获取更多信息。(这段翻译不太理想)

   You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:

    我们可以在try-with-resources中声明一个或多个资源。下面的例子从zipFileName这个zip文件中检索出文件的包名称并写入到一个文本文件中。

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());
        }
    }
}

   In this example, the try-with-resources statement contains two declarations that are separated by a semicolon: ZipFile and BufferedWriter. When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order. Note that the close methods of resources are called in theoppositeorder of their creation.
    在这个例子中,try-with-resources中声明了两个资源并通过分号进行了分割:ZipFile与BufferedWriter。当代码块紧跟着声明的后面,无论正常执行还是抛出异常,BufferedWriter与ZipFileclose对象的close方法将会被按一定顺序被执行。这个顺序与它们创建的方法相反。

   The following example uses a try-with-resources statement to automatically close a java.sql.Statement object:

    下面的例子使用try-with-resources的方式来自动关闭java.sql.Statement对象:

public static void viewTable(Connection con) throws SQLException {

    String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES";

    try (Statement stmt = con.createStatement()) {
        ResultSet rs = stmt.executeQuery(query);

        while (rs.next()) {
            String coffeeName = rs.getString("COF_NAME");
            int supplierID = rs.getInt("SUP_ID");
            float price = rs.getFloat("PRICE");
            int sales = rs.getInt("SALES");
            int total = rs.getInt("TOTAL");

            System.out.println(coffeeName + ", " + supplierID + ", " + 
                               price + ", " + sales + ", " + total);
        }
    } catch (SQLException e) {
        JDBCTutorialUtilities.printSQLException(e);
    }
}

The resource java.sql.Statement used in this example is part of the JDBC 4.1 and later API.
本例中使用的java.sql.Statement要求JDBC的版本必须是4.1或者之后版本。
Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.

注意:try-with-resources声明可以像普通的try声明一样同时拥有catch块与finally块。在使用try-with-resources时,任意catch块或者finally块都会在资源关闭后运行。

Suppressed Exceptions

  An exception can be thrown from the block of code associated with the try-with-resources statement. In the example writeToFileZipFileContents, an exception can be thrown from the try block, and up to two exceptions can be thrown from the try-with-resources statement when it tries to close the ZipFile and BufferedWriter objects. If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the writeToFileZipFileContents method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.

  异常可以从一个try-with-resources声明中抛出。在例子writeToFileZipFileContents中,异常可以从try块中正常抛出,而且可以同时抛出多个异常,如果在关闭多个资源对象的时候。如果一个异常是从try块中抛出,一个或多个异常从try-with-resources声明中抛出,这样从try-with-resources抛出的异常就会被抑制,并且抛出的方法是被writeToFileZipFileContents的方法抛出的。我们可以使用Throwable.getSuppressed方法来获取被抑制的异常。

Classes That Implement the AutoCloseable or Closeable Interface

  See the Javadoc of the AutoCloseable and Closeable interfaces for a list of classes that implement either of these interfaces. The Closeable interface extends the AutoCloseable interface. The close method of the Closeable interface throws exceptions of type IOException while the close method of the AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close method to throw specialized exceptions, such as IOException, or no exception at all.

  查看AutoCloseable接口与Closeable接口的Javadoc文档,我们可以看到实现这些接口的类的列表。Closeable接口继承了AutoCloseable接口。Closeable接口的close方法在AutoCloseable接口抛出Exception类型的异常,Closeable接口的close方法就会抛出一个IOException异常。因此AutoCloseable接口的子类可以覆写close 方法抛出的特定异常,就像IOException或者没有异常。

下面是通俗易懂的介绍:

  JDK7以前如果rd.readLine()与rd.close()(在finally块中)都抛出异常则只会抛出finally块中的异常,不会抛出rd.readLine();中的异常。这样经常会导致得到的异常信息不是调用程序想要得到的。
  JDK7及以后版本中如果采用try-with-resource机制,如果在try-with-resource声明中抛出异常(可能是文件无法打或都文件无法关闭)同时rd.readLine();也抛出异常,则只会抛出rd.readLine()的异常。

  在JDK7中只要实现了AutoCloseable或Closeable接口的类或接口,都可以使用try-with-resource来实现异常处理和资源关闭。但是注意异常抛出顺序。在Java se 7中的try-with-resource机制中异常的抛出顺序与Java se 7以前的版本有一点不一样,是先声明的资源后关闭。

赞赏

 

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值