原文链接:
原文:
The try-with-resources Statement
The try-with-resources statement is a try statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
The following example reads the first line from a file. It uses an instance of BufferedReader to read data from the file. BufferedReader is a resource that must be closed after the program is finished with it:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
In this example, the resource declared in the try-with-resources statement is a BufferedReader. The declaration statement appears within parentheses immediately after the try keyword. The class BufferedReader, in Java SE 7 and later, implements the interface java.lang.AutoCloseable. Because the BufferedReader instance is declared in a try-with-resource statement, it will be closed regardless of whether the try statement completes normally or abruptly (as a result of the method BufferedReader.readLine throwing an IOException).
Prior to Java SE 7, you can use a finally block to ensure that a resource is closed regardless of whether the try statement completes normally or abruptly. The following example uses a finally block instead of a try-with-resources statement:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
However, in this example, if the methods readLine and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finally block; the exception thrown from the try block is suppressed. In contrast, in the example readFirstLineFromFile, if exceptions are thrown from both the try block and the try-with-resources statement, then the method readFirstLineFromFile throws the exception thrown from the try block; the exception thrown from the try-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the section Suppressed Exceptions for more information.
You may declare one or more resources in a try-with-resources statement. The following example retrieves the names of the files packaged in the zip file zipFileName and creates a text file that contains the names of these files:
public static void writeToFileZipFileContents(String zipFileName,
String outputFileName)
throws java.io.IOException {
java.nio.charset.Charset charset =
java.nio.charset.StandardCharsets.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());
}
}
}
In this example, the try-with-resources statement contains two declarations that are separated by a semicolon: ZipFile and BufferedWriter. When the block of code that directly follows it terminates, either normally or because of an exception, the close methods of the BufferedWriter and ZipFile objects are automatically called in this order. Note that the close methods of resources are called in the opposite order of their creation.
The following example uses a try-with-resources statement to automatically close a java.sql.Statement object:
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);
}
}
The resource java.sql.Statement used in this example is part of the JDBC 4.1 and later API.
Note: A try-with-resources statement can have catch and finally blocks just like an ordinary try statement. In a try-with-resources statement, any catch or finally block is run after the resources declared have been closed.
Suppressed Exceptions
An exception can be thrown from the block of code associated with the try-with-resources statement. In the example writeToFileZipFileContents, an exception can be thrown from the try block, and up to two exceptions can be thrown from the try-with-resources statement when it tries to close the ZipFile and BufferedWriter objects. If an exception is thrown from the try block and one or more exceptions are thrown from the try-with-resources statement, then those exceptions thrown from the try-with-resources statement are suppressed, and the exception thrown by the block is the one that is thrown by the writeToFileZipFileContents method. You can retrieve these suppressed exceptions by calling the Throwable.getSuppressed method from the exception thrown by the try block.
Classes That Implement the AutoCloseable or Closeable Interface
See the Javadoc of the AutoCloseable and Closeable interfaces for a list of classes that implement either of these interfaces. The Closeable interface extends the AutoCloseable interface. The close method of the Closeable interface throws exceptions of type IOException while the close method of the AutoCloseable interface throws exceptions of type Exception. Consequently, subclasses of the AutoCloseable interface can override this behavior of the close method to throw specialized exceptions, such as IOException, or no exception at all.
译文:
try-with-resources语句
try-with-resources语句是一个声明了一个或是多个资源的语句。一 个资源是一个在程序完成后一定会关闭的对象。try-with-resources语句保证 了没个资源在语句结尾时关闭。实现了java.lang.AutoCloseable接口的任何对象,他包括所有实现了java.io.Closeable接口的对象,能被作为一个资源使用。
下面的例子第一行读取了一个文件,它使用了一个bufferedreader类的实例来从文件里读取数据。BufferedReader类 是一个在程序完成后一定会关闭的的资源。
在这个例子中,在try-with-resources语句中声明的资源是一个BufferedReader类。这个声明语句出现在try关键字之后的花括号里。BufferedReader类,在JAVA se7以及后续版本中,实现了java.lang.AutoCloseable接口。因为BufferedReader类实例被声明在了一个try-with-resource语句中,不管try语句是否正常完成,或者突然完成,它都会关闭(这是由于BufferedReader.readLine方法的结果会抛出一个IOException异常)。
在Java SE7之前,你会使用finally语句块来确定一个资源无论try语句正常完成还是突然完成而关闭。下面的例子使用了一个finaly语句块代替一个try-with-resources语句:
然而,在这个例子中,如果readLine以及close方法都抛出了异常,那么readFirstLineFromFileWithFinallyBlock方法会抛出一个从finally语句块中抛出的异常,如果异常从try语句块以及try-with-resources语句中都被抛出,接下来readFirstLineFromFile 方法会抛出从try语句块中抛出的异常,从try-with-resources语句块中抛出的异常会被抑制。在Java SE7以及后续版本中,你可以检索出被抑制的异常,你可以在抑制异常这一节中了解到更多信息。
你可能会在一个try-with-resources语句中声明一个或多个资源,下面的例子检索了打包成zip文件zipFileName的文件名字并创建了一个包含了这些文件的名字的文本文件。
在这个例子中,try-with-resources语句包含了两个被分号隔开的声明:ZipFile和BufferedWriter。当直接跟随他的代码块因为正常,要么是或者异常终止时,BufferedWriter 和 ZipFile对象的关闭方法会被这个命令自动调用。注意,资源的关闭方法调用顺序与他们创造的顺序相反。
下面的例子使用了一个try-with-resources语句来自动关闭一个java.sql.Statement 对象:
在这个例子中被用到的java.sql.Statement资源是JDBC4.1以及它的后续版本中的一部分。
抑制异常
一个异常会从一块和try-with-resources语句联系的代码块被抛出。在这个例子writeToFileZipFileContents中,一个异常会从try语句块中被抛出,直到当它尝试去关闭ZipFile和BufferredWriter对象时,抛出从try-with-resources语句中的两个异常。如果一个异常从try语句块被抛出,一个或多个异常从try-with-resources语句中被抛出,那么这些从try-with-resources语句被抛出的异常会被抑制,从块被抛出的异常是被writeToFileZipFileContents 方法抛出的异常。你可以通过从try语句块中抛出的异常,调用Throwable.getSuppressed方法来检索这些被抑制的异常。
实现AutoCloseable或者Closeable接口的类
有关实现这两个接口的类的列表,你可以查阅Java相关文档。Closeable接口继承了AutoCloseable接口。当AutoCloseable 接口的close方法抛出Exception类型的异常时,Closeable 接口的close方法抛出IOException类型的异常。
因此,AutoCloseable 接口的子类能重写close方法,从而抛出专门的异常,就像IOException,或者没有异常。