Java 7 新特性try-with-resources语句

翻译 2017年07月04日 22:10:41

1、什么是try-with-resources语句

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

2、举个栗子

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

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 语句:

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 方法均抛出异常,那么 readFirstLineFrom FileWithFinallyBlock 方法将抛出从 finally 块中抛出的异常; try 块中抛出的异常被抑制了。与此相反, 在 readFirstLineFromFile 这个例子中, 如果 try 块和 try-with-resources 语句均抛出异常, 那么 readFirstLineFromFile 将抛出从 try 块中抛出的异常; try-with-resources 块抛出的异常被抑制了。在java SE 7 以及后续的版本中, 你可以检索被抑制的异常;详情参见 Suppressed Exceptions

      可以在一个 try-with-resources 语句中声明一个或多个资源。下面的例子检索zip文件 zipFileName 中所有文件的名称并创建一个包含那些文件名称的文本文件:

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

java.nio.charset.Charset charset = 
                       java.nio.charset.Charset.forName("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());
    }
  }
 }

       在这个例子中, try-with-resources 语句包含两个由分号隔开的声明: ZipFileBufferedWriter。当代码块直接伴随着它正常地或由于一个异常终止时, BufferedWriterZipFile 对象的 close 方法以这种顺序自动地调用 。

注意:资源的 close 方法调用顺序与它们的创建顺序相反。



下面的例子使用一个 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);
   }
}

这个例子中使用的 java.sql.Statement 这个资源是JDBC 4.1以及后续版本API的一部分。

注意: 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。

3、被抑制的异常

       与 try-with-resources 语句关联的代码块可能会抛出异常。在 writeToFileZipFileContents这个例子中, 当试图关闭 ZipFileBufferedWriter 对象时,try 块可能会抛出一个异常,并且 try-with-resources 语句可能抛出多达两个异常 。如果 try 块抛出异常并且 try-with-resources 语句抛出一个或多个异常,那么从 try-with-resources 语句中抛出的异常将会被抑制, 并且块抛出的异常是由 writeToFileZipFileContents 方法抛出的那一个。你可以通过调用由 try块抛出的异常的Throwable.getSuppressed 方法检索这些被抑制的异常信息。

4、实现了AutoCloseable 或 Closeable 接口的类

      参见 AutoCloseableCloseable 接口的Javadoc可以看到实现了两者当中的任何一个接口的类集。Closeable 接口继承了 AutoCloseable 接口。 Closeable接口的 close 方法抛出IOException 类型的异常而 AutoCloseable 接口的 close 方法抛出 Exception 类型的异常。因此, AutoCloseable 接口的子类可以重写 close 方法的这个行为来抛出指定的异常,例如 IOException,或者没有异常。




对机器学习,人工智能感兴趣的小伙伴,请关注我的公众号:

这里写图片描述



参考文献:

  1. http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html

Java SE7新特性之try-with-resources语句

try-with-resources语句是一个声明一个或多个资源的 try 语句。一个资源作为一个对象,必须在程序结束之后随之关闭。 try-with-resources语句确保在语句的最后每个资源都...

Java7 新特性:try() 语句 即 try-with-resources

Try-with-resources是java7中一个新的异常处理机制,它能够很容易地关闭在try-catch语句块中使用的资源。 利用Try-Catch-Finally管理资源(旧的代码风...

java7新特性之Try-with-resources statement

try-with-resources 语句是一个声明了1到多个资源的try语句。资源是指这个try执行完成后必需close掉的对象,比如connection, resultset等。 try-wit...
  • ynwso
  • ynwso
  • 2012年01月30日 23:43
  • 13088

Java 7 try-with-resources自动关闭资源

Java 7开始,提供了一种新的语法try-with-resources用于在资源使用完毕后自动关闭资源,和python中的with语句类似。“资源”指的是实现了java.lang.AutoClose...

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

翻译自官方提供的使用说明。

java新特性之try-with-resources

这个所谓的try-with-resources,是个语法糖。实际上就是自动调用资源的close()函数。和Python里的with语句差不多。 例如: [java] vie...
  • CillyB
  • CillyB
  • 2016年10月10日 19:21
  • 196

JDK1.7新特性之try-with-resources和catch多种异常

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

Java SE 7 中带资源声明的 try 语句(try-with-resources statement)

Java SE 7 中的 try-with-resources statement 是指声明了一个或多个资源的 try 语句(声明),其中的资源一般是指在程序执行完毕後需要关闭的对象,而在 try-w...

Java7新语法 -try-with-resources

使用try-with-resources, 可以自动关闭实现了AutoCloseable或者Closeable接口的资源。
  • fw0124
  • fw0124
  • 2015年11月20日 15:32
  • 3444
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Java 7 新特性try-with-resources语句
举报原因:
原因补充:

(最多只允许输入30个字)