Oracle官方文档: http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html

概述

Java SE 7以及后续版本中, 增加了 try-with-resources 语句,与传统 try 语句在结构上看在 try 后多了一个括号()

  1. try-with-resources语句是一个声明一个或多个资源的 try 语句。
  2. 任何实现了 Java.lang.AutoCloseable的对象, 包括所有实现了 java.io.Closeable 的对象, 都可以用作一个资源。
  3. 一个资源作为一个对象,必须在程序结束之后随之关闭。
  4. try-with-resources语句确保在语句的最后每个资源都被关闭 。
  5. 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。
  6. 形如
try (
try-with-resources 语句块
)
{
try 语句块
} catch() {
statements
} finally {
statements
}

用例

例1

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

readFirstLineFromFile

    static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
  1. 在这个例子中, try-with-resources 语句声明的资源是一个 BufferedReader。声明语句需要在紧跟在 try 关键字的括号里面。
  2. Java SE 7以及后续版本中,BufferedReader类实现了java.lang.AutoCloseable接口。
  3. 因为 BufferedReader 实例是在 try-with-resource 语句中声明的, 所以不管 try 语句正常地完成或是 发生意外 (结果就是 BufferedReader.readLine 方法抛出IOException),BufferedReader都将会关闭。

例2

readFirstLineFromFileWithFinallyBlock

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
  1. 在 Java SE 7之前, 可以使用 finally 块来确保资源被关闭,不管 try 语句正常地完成或是发生意外。上面的例子使用 finally 块替换 try-with-resources 语句.
  2. 然而,在上面的例子中,如果 readLine 和 close 方法均抛出异常,那么readFirstLineFromFileWithFinallyBlock方法将抛出从 finally 块中抛出的异常,try 块中抛出的异常被挂起(Suppressed)。
  3. 与此相反, 在 readFirstLineFromFile 这个例子中, 如果 try 块和 try-with-resources 语句均抛出异常, 那么 readFirstLineFromFile 将抛出从 try 块中抛出的异常; try-with-resources 块抛出的异常被挂起。
  4. 在javaSE7以及后续的版本中,你可以检索挂起的异常(#1111);详情参见 Suppressed Exceptions
  5. 可以在一个 try-with-resources 语句中声明一个或多个资源。下面的例子检索zip文件 zipFileName 中所有文件的名称并创建一个包含那些文件名称的文本文件:

例3

import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.zip.ZipFile;
import java.io.BufferedWriter;
import java.nio.file.Files;
import java.util.Enumeration;
import java.util.zip; public static void writeToFileZipFileContents(String zipFileName, String outputFileName)
throws java.io.IOException { Charset charset = java.nio.charset.Charset.forName("US-ASCII");
Path outputFilePath = java.nio.file.Paths.get(outputFileName);
// 打开 zip 文件并使用 try-with-resources 语句创建输出文件
try (
ZipFile zf = new java.util.zip.ZipFile(zipFileName);
BufferedWriter writer = Files.newBufferedWriter(outputFilePath, charset)
) {
// 枚举每个表项
for (Enumeration entries = zf.entries(); entries.hasMoreElements();) {
// 获取表项的名字并写入输出文件中
String newLine = System.getProperty("line.separator");
String zipEntryName = ((ZipEntry)entries.nextElement()).getName() + newLine;
writer.write(zipEntryName, 0, zipEntryName.length());
}
}
}
  1. 在这个例子中, try-with-resources 语句包含两个由分号隔开的声明: ZipFile 和 BufferedWriter。
  2. 当代码块直接伴随着它正常地或由于一个异常终止时, BufferedWriter 和 ZipFile 对象的 close 方法以这种顺序自动地调用 。注意:资源的 close 方法调用顺序与它们的创建顺序相反。

例4

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

挂起的异常(Suppressed Exceptions)

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

实现了AutoCloseable 或 Closeable 接口的类

  1. Closeable 接口继承了 AutoCloseable 接口。
  2. Closeable接口的 close 方法抛出IOException 类型的异常而 AutoCloseable 接口的 close 方法抛出 Exception 类型的异常。因此, subclasses of the AutoCloseable 接口的子类可以重写 close 方法的这个行为来抛出指定的异常,例如 IOException, 或者没有异常。









Java异常处理之try-with-resources的更多相关文章

  1. Java—异常处理总结

    异常处理是程序设计中一个非常重要的方面,也是程序设计的一大难点,从C开始,你也许已经知道如何用if...else...来控制异常了,也许是自发的,然而这种控制异常痛苦,同一个异常或者错误如果多个地方出 ...

  2. Java异常处理总结Exception\Error

    Java异常处理总结Exception\Error 2012-12-28 08:17:17|  分类: JAVA |  标签:java  |举报|字号 订阅   Java异常处理总结          ...

  3. Java 异常处理的十个建议

    前言 Java异常处理的十个建议,希望对大家有帮助~ 本文已上传github: https://github.com/whx123/JavaHome 公众号:捡田螺的小男孩 一.尽量不要使用e.pri ...

  4. 札记:Java异常处理

    异常概述 程序在运行中总会面临一些"意外"情况,良好的代码需要对它们进行预防和处理.大致来说,这些意外情况分三类: 交互输入 用户以非预期的方式使用程序,比如非法输入,不正当的操作 ...

  5. java异常处理(父子异常的处理)

    我当初学java异常处理的时候,对于父子异常的处理,我记得几句话“子类方法只能抛出父类方法所抛出的异常或者是其子异常,子类构造器必须要抛出父类构造器的异常或者其父异常”.那个时候还不知道子类方法为什么 ...

  6. Java 异常处理

    异常是程序中的一些错误,但并不是所有的错误都是异常,并且错误有时候是可以避免的. 比如说,你的代码少了一个分号,那么运行出来结果是提示是错误java.lang.Error:如果你用System.out ...

  7. 《转载》Java异常处理的10个最佳实践

    本文转载自 ImportNew - 挖坑的张师傅 异常处理在编写健壮的 Java 应用中扮演着非常重要的角色.异常处理并不是功能性需求,它需要优雅地处理任何错误情况,比如资源不可用.非法的输入.nul ...

  8. JAVA 异常处理机制

    主要讲述几点: 一.异常的简介 二.异常处理流程 三.运行时异常和非运行时异常 四.throws和throw关键字 一.异常简介 异常处理是在程序运行之中出现的情况,例如除数为零.异常类(Except ...

  9. Java异常处理和设计

    在程序设计中,进行异常处理是非常关键和重要的一部分.一个程序的异常处理框架的好坏直接影响到整个项目的代码质量以及后期维护成本和难度.试想一下,如果一个项目从头到尾没有考虑过异常处理,当程序出错从哪里寻 ...

  10. 深入理解java异常处理机制

       异常指不期而至的各种状况,如:文件找不到.网络连接失败.非法参数等.异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程.Java通 过API中Throwable类的众多子类描述各种不同的 ...

随机推荐

  1. JavaFX 简介

    JavaFX 介绍一提到Java的图形界面库,我们通常听到的都是Swing,或者更老一点的AWT,包括很多书上面介绍的也都是这两种.很多学校.培训班教学的也是这两种技术.但是其实这两种技术都已经过时很 ...

  2. 4.Zuul-限流

    令牌桶 限流流程图: RateLimitFilter : package com.wangfajun.filter; import com.alibaba.fastjson.JSON; import ...

  3. HDU 1892(书架统计 二维树状数组)

    题意是在二维平面上在一些位置上进行数据的增删改查操作,使用树状数组(了解树状数组点这里) 原来的树状数组在求区间和时是 sum( x, y ) = getsum( y ) - getsum( x - ...

  4. 海南医院帆软报表 最终版本SQL

    1. 挂号微信收入明细 -- WANTED-1283 门诊查询统计报表-挂号微信收入明细 select p.name as patientName, -- 患者姓名 p.birthday, -- 出生 ...

  5. XXE攻防总结

    1. 前言与XML格式相同的web漏洞,比较广泛的共有xpath注入.xml注入.soap注入.XXE四种. 2. XML相关的介绍针对xml语言,要明白两个特性:合法性与合理性.所谓合法性,是指语法 ...

  6. Linux查看版本信息

    查看Linux版本以及是32位还是64位 查看版本 一.查看Linux内核版本命令(两种方法): 1.cat /proc/version [root@S-CentOS home]# cat /proc ...

  7. 理解PHP中的会话控制

    会话控制是一种跟踪用户的通信方式,使用会话控制主要基于以下几点:由于http协议的无状态性,使得不能通过协议来建立两次请求之间的关联:对于通常的页面之间的数据传递方式get和post而言,主要处理参数 ...

  8. Docker 容器CPU设置

    CPU使用率其实就是你运行的程序占用的CPU资源,表示你的机器在某个时间点的运行程序的情况.使用率越高,说明你的机器在这个时间上运行了很多程序,反之较少.CPU使用率的高低与你的CPU强弱有直接关系. ...

  9. VM4061 layui.js:2 Layui hint: form is not a valid module

    报错:VM4061 layui.js:2 Layui hint: form is not a valid module 解决办法:当你遇到类似这样报错,说某某某不是一个有效的模块时,不防在layui. ...

  10. 第27月第17天 objc_msgSendSuper

    1.objc_msgSendSuper super 的含义,消息转发会调用 objc_msgSendSuper, 就是 去父类的方法列表中找到 initWithFrame:这个方法,然后调用,调用的主 ...