文档章节

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

JackieYeah
 JackieYeah
发布于 2016/04/11 20:01
字数 1153
阅读 6
收藏 0

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

       下面的例子读取文件的第一行。它使用了 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 方法均抛出异常,那么 readFirstLineFromFileWithFinallyBlock 方法将抛出从 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 语句包含两个由分号隔开的声明: ZipFile 和 BufferedWriter。当代码块直接伴随着它正常地或由于一个异常终止时, BufferedWriter 和 ZipFile 对象的 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 块都是在声明的资源被关闭以后才运行。

被抑制的异常

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

实现了AutoCloseable 或 Closeable 接口的类

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


       本文翻译自Oracle官方文档http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html,如有不正确的地方,敬请指正,谢谢!

© 著作权归作者所有

上一篇: Java代理模式
下一篇: Java反射机制
JackieYeah
粉丝 45
博文 70
码字总数 90004
作品 0
武汉
程序员
私信 提问
JDK7 特性之 try-with-resource 资源的自动管理

JDK7 特性之 try-with-resource 资源的自动管理 在java7以前,程序中使用的资源需要被明确地关闭 demo如下 try-with-resource 结构(jdk7 新特性) 该try-with资源语句是try声明了一个或多个资...

晨猫
2018/12/26
19
0
一起学Java7新功能扩展——深入历险分享(一)

特此声明:因网友疑问,这里声明一个重要的安全,就是大家所知的java惊现0day漏洞!8月30日,Oralce紧急发布了新版本的JDK和JRE,原因是发现了一个严重的0day漏洞CVE-2012-4681,远程攻击者可...

Beyond-Bit
2012/09/03
4.2K
26
从java1到java9每个版本都有什么新特性?

每次出新版本,大家大概都会这么问,“Java X会有什么特性呢?” 。在下面的内容里,我总结了至今为止的Java主要发行版中各自引入的新特性,这样做的目的是为了突出各个新特性是在哪个发行版...

Java红茶
2017/11/12
0
0
Java 代码字节:足智多谋的 Try-With-Resources

本文由ImportNew -PJing 翻译自dzone。欢迎加入翻译小组。转载请见文末要求。 当通过 Java 实现业务实例时,对资源进行处理是司空见惯的。一般情况下,资源(如文件或 socket 句柄)封装在对...

ImportNew
2018/09/26
0
0
从java1到java9每个版本都有什么新特性?五分钟了解

     其实,我是个标题党,没有java1的说法,java9的新特性我也没总结。所以,来个关注吧,说不定哪天就出了呢。。。   每次出新版本,大家大概都会这么问,“Java X会有什么特性呢?”...

java进阶架构师
2017/11/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Rust 的 GUI 框架生态概览

本文比较全面比较了目前主流的 Rust 的 GUI 框架的表现。其中 ++ 表示非常好,-- 表示非常差,而 o 表示处于平均水平。 参与对比的框架共有 8 个,详细的比较结果如下: Electron + Neon El...

红薯
32分钟前
4
0
golang微服务框架go-micro 入门笔记2.1 micro工具之micro api

micro api micro 功能非常强大,本文将详细阐述micro api 命令行的功能 重要的事情说3次 本文全部代码https://idea.techidea8.com/open/idea.shtml?id=6 本文全部代码https://idea.techidea8....

非正式解决方案
今天
4
0
Spring Context 你真的懂了吗

今天介绍一下大家常见的一个单词 context 应该怎么去理解,正确的理解它有助于我们学习 spring 以及计算机系统中的其他知识。 1. context 是什么 我们经常在编程中见到 context 这个单词,当...

Java知其所以然
昨天
3
0
Spring Boot + Mybatis-Plus 集成与使用(二)

前言: 本章节介绍MyBatis-Puls的CRUD使用。在开始之前,先简单讲解下上章节关于Spring Boot是如何自动配置MyBatis-Plus。 一、自动配置 当Spring Boot应用从主方法main()启动后,首先加载S...

伴学编程
昨天
7
0
用最通俗的方法讲spring [一] ──── AOP

@[TOC](用最通俗的方法讲spring [一] ──── AOP) 写这个系列的目的(可以跳过不看) 自己写这个系列的目的,是因为自己是个比较笨的人,我曾一度怀疑自己的智商不适合干编程这个行业.因为在我...

小贼贼子
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部