Java SE7新特性之try-with-resources语句
2016-04-07 00:00
459 查看
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, 或者没有异常。
相关文章推荐
- Java——流程控制与数组
- java成神之路
- jdk容器之HashMap
- Ehcache 整合Spring 使用页面、对象缓存
- 打造高性能Java应用需掌握的5大知识
- Java新特性
- java反射机制
- spring核心IOC和DI的区别
- java 反射加实例化内部类
- JAVA开发环境变量配置
- Java正则表达式教程及示例
- java数据同步陷阱
- 很简单的JAVA反射教程
- 设计模式--适配器模式
- 设计模式--抽象工厂模式
- 设计模式--桥接模式
- 设计模式--建造者模式
- maven版本对应的jdk版本
- eclipse如何修改dynamic web module version
- @ModelAttribute注解和SpringMVC表单modelAttribute属性