详解 try-with-resource
Oracle官方文档: http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html
概述
Java SE 7以及后续版本中, 增加了 try-with-resources 语句,与传统 try 语句在结构上看在 try 后多了一个括号()
try-with-resources语句是一个声明一个或多个资源的 try 语句。- 任何实现了 Java.lang.AutoCloseable的对象, 包括所有实现了 java.io.Closeable 的对象, 都可以用作一个资源。
- 一个资源作为一个对象,必须在程序结束之后随之关闭。
- try-with-resources语句确保在语句的最后每个资源都被关闭 。
- 一个 try-with-resources 语句可以像普通的 try 语句那样有 catch 和 finally 块。在try-with-resources 语句中, 任意的 catch 或者 finally 块都是在声明的资源被关闭以后才运行。
- 形如
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();
}
}
- 在这个例子中, try-with-resources 语句声明的资源是一个 BufferedReader。
声明语句需要在紧跟在 try 关键字的括号里面。 - Java SE 7以及后续版本中,BufferedReader类实现了java.lang.AutoCloseable接口。
- 因为 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();
}
}
在 Java SE 7之前, 可以使用 finally 块来确保资源被关闭,不管 try 语句正常地完成或是发生意外。上面的例子使用 finally 块替换 try-with-resources 语句.- 然而,在上面的例子中,如果 readLine 和 close 方法均抛出异常,那么readFirstLineFromFileWithFinallyBlock方法将抛出从 finally 块中抛出的异常,try 块中抛出的异常被挂起(Suppressed)。
- 与此相反, 在 readFirstLineFromFile 这个例子中, 如果 try 块和 try-with-resources 语句均抛出异常, 那么 readFirstLineFromFile
将抛出从 try 块中抛出的异常; try-with-resources 块抛出的异常被挂起。 - 在javaSE7以及后续的版本中,你可以检索挂起的异常(#1111);详情参见 Suppressed Exceptions
- 可以在一个 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());
}
}
}
- 在这个例子中, try-with-resources 语句包含两个由分号隔开的声明: ZipFile 和 BufferedWriter。
- 当代码块直接伴随着它正常地或由于一个异常终止时, 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)
- 与 try-with-resources 语句关联的代码块可能会抛出异常。
- 在 writeToFileZipFileContents这个例子中, 当试图关闭 ZipFile 和 BufferedWriter 对象时,try 块可能会抛出一个异常,并且 try-with-resources 语句可能抛出多达两个异常 。
- 如果 try 块抛出异常并且 try-with-resources 语句抛出一个或多个异常,那么从 try-with-resources 语句中抛出的异常将会挂起, 并且块抛出的异常是由 writeToFileZipFileContents 方法抛出的那一个。
- 你可以通过调用由 try块抛出的异常的Throwable.getSuppressed 方法检索这些挂起的异常信息。
实现了AutoCloseable 或 Closeable 接口的类
- Closeable 接口继承了 AutoCloseable 接口。
- Closeable接口的 close 方法抛出IOException 类型的异常而 AutoCloseable 接口的 close 方法抛出 Exception 类型的异常。因此, subclasses of the AutoCloseable 接口的子类可以重写 close 方法的这个行为来抛出指定的异常,例如 IOException, 或者没有异常。
详解 try-with-resource的更多相关文章
- 【转】HTTP协议详解
原文地址:http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html 一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则 ...
- 图文详解互联网根基之HTTP
这是本人对<图解HTTP>和<HTTP权威指南>阅读后总结的大家常用的.重要的知识点,前端.后端同学居家必备! 一.概述 HTTP是Hyper Text Transfer Pr ...
- HTTP 协议详解(转载)
原文: http://kb.cnblogs.com/page/130970/#httpmeessagestructe HTTP协议详解 当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, ...
- HTTP协议图示详解
一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规则,超文本传输协议(HTTP)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器. ...
- Fiddldr 教程之:HTTP协议详解(转)
原文地址:http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html HTTP协议详解 当今web程序的开发技术真是百家争鸣,ASP ...
- (转)写的非常好的一篇HTTP协议详解
原文地址:http://www.cnblogs.com/TankXiao/archive/2012/02/13/2342672.html#3931004(推荐看原文,因为原文文章末有更详细链接) 当今 ...
- HTTP协议 (一) HTTP协议详解
当今web程序的开发技术真是百家争鸣,ASP.NET, PHP, JSP,Perl, AJAX 等等. 无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了We ...
- 【转载】HTTP协议详解
[本文转自]http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html 一.概念 协议是指计算机通信网络中两台计算机之间进行通信所必须共同遵守的规定或规 ...
- Http协议详解(转)>>>写的很好
声明:本片文章非原创,仅供自己学习并分享 内容来源于博客园作者MIN飞翔的HTTP协议详解地址http://www.cnblogs.com/EricaMIN1987_IT/p/3837436.html ...
- HTTP数据包详解
无论Web技术在未来如何发展,理解Web程序之间通信的基本协议相当重要, 因为它让我们理解了Web应用程序的内部工作. 本文将对HTTP协议进行详细的实例讲解,内容较多,希望大家耐心看. 阅读目录 ...
随机推荐
- Docker - 访问容器
容器具有自己的内部网络和ip地址,具体信息可以查看docker inspect命令结果的"NetworkSettings"部分. 如果想要从外部访问容器中的应用,可以通过docke ...
- Power Pivot表属性无法切换回表预览模式的问题
近期Office365用户升级后解决了在Power Pivot中输入中文的问题,但是同时也带来了一个新的问题就是表属性窗口默认为“查询编辑器”模式,且无法切换回“表预览”模式. 本文和您分享在这种情况 ...
- sublime Text2 快捷键精华版
Ctrl+Shift+P:打开命令面板Ctrl+P:搜索项目中的文件Ctrl+G:跳转到第几行Ctrl+W:关闭当前打开文件Ctrl+Shift+W:关闭所有打开文件Ctrl+Shift+V:粘贴 ...
- 调停者(Mediator)模式
调停者模式是对象的行为模式.调停者模式包装了一系列对象相互作用的方式,使得这些对象不必相互明显引用.从而使它们可以较松散地耦合.当这些对象中的某些对象之间的相互作用发生改变时,不会立即影响到其他的一些 ...
- keydown - > keypress - > keyup 用法和区别
英文输入法: 事件触发顺序:keydown - > keypress - > keyup 中文输入法: firfox:输入触发keydown,回车确认输入触发keyup chr ...
- 基于HTML5 Canvas实现用户交互
很多人都有这样的疑问,基于HTML5 Canvas实现的元素怎么和用户进行交互?在这里我们用到HT for Web(http://www.hightopo.com/guide/guide/core/b ...
- hello Kotlin!
听说谷爹要把Kotlin作为了Android开发的一级语言,吓得我赶紧写个“Hello Kotlin!”压压惊! Kotlin是由JetBrains 公司开发的语言,并且已经开源.而JetBrains ...
- 开涛spring3(6.3) - AOP 之 6.3 基于Schema的AOP
6.3 基于Schema的AOP 基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面.切入点及声明通知. 在Spring配置文件中,所以AOP相关定义必须放在<a ...
- Android框架式编程之BufferKnife
配置 compile 'com.jakewharton:butterknife:(insert latest version)' annotationProcessor 'com.jakewharto ...
- Servlet 详解
1.什么是 Servlet? Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序 ...