我们在使用try catch 资源的的时候 常常忘记释放资源,比如JDBC连接,那么下边讲的AutoCloseable 就是解决这个问题:资源自动释放。
The
try
-with-resources statement is atry
statement that declares one or more resources. A resource is an object that must be closed after the program is finished with it. Thetry
-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implementsjava.lang.AutoCloseable
, which includes all objects which implementjava.io.Closeable
, can be used as a resource.
带有resources的try语句声明一个或多个resources。resources是在程序结束后必须关闭的对象。try-with-resources语句确保在语句末尾关闭每个resources。任何实现java.lang.AutoCloseable,包括实现了java.io.Closeable的类,都可以
作为resources使用。
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:
下边这个例子是从一个文件里读第一行,它用了一个BufferedReader实例去从文件里读数据。BufferedReader是一个程序运行完后,必须关闭的资源。
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 aBufferedReader
. The declaration statement appears within parentheses immediately after thetry
keyword. The classBufferedReader
, in Java SE 7 and later, implements the interfacejava.lang.AutoCloseable
. Because theBufferedReader
instance is declared in atry
-with-resource statement, it will be closed regardless of whether thetry
statement completes normally or abruptly (as a result of the methodBufferedReader.readLine
throwing anIOException
).
在上边这个例子中,被声明在try
-with-resources的资源是BufferedReader,这个声明语句出现在try关键字后面的括号中,这个BufferedReader类,在Java7之后的版本中,实现这个java.lang.AutoCloseable接口,因为BufferedReader实例是被声明在try
-with-resource 语句中,不管try语句是正常完成还是抛异常( BufferedReader的readLine方法抛出IOException的异常),这个资源都将被关闭。
Prior to Java SE 7, you can use a
finally
block to ensure that a resource is closed regardless of whether thetry
statement completes normally or abruptly. The following example uses afinally
block instead of atry
-with-resources statement:
在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();
}
}
However, in this example, if the methods
readLine
andclose
both throw exceptions, then the methodreadFirstLineFromFileWithFinallyBlock
throws the exception thrown from thefinally
block; the exception thrown from thetry
block is suppressed. In contrast, in the examplereadFirstLineFromFile
, if exceptions are thrown from both thetry
block and thetry
-with-resources statement, then the methodreadFirstLineFromFile
throws the exception thrown from thetry
block; the exception thrown from thetry
-with-resources block is suppressed. In Java SE 7 and later, you can retrieve suppressed exceptions; see the section Suppressed Exceptions for more information.
但是,在上边例中,如果方法readLine和close两个抛出异常,那么方法readFirstLineFromFileWithFinallyBlock将从finally抛出的异常抛出;从try块抛出的异常被抑制。相反,在readFirstLineFromFile示例中,如果从try块和try-with-resources语句抛出异常,那么方法readFirstLineFromFile将抛出从try块抛出的异常;禁止从带有资源的try块抛出异常。在Java SE 7及更高版本中,您可以检索受抑制的异常;有关更多信息,请参阅“禁止异常”一节。
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:
你可以在try-with-resources语句里声明一个或者多个资源。下边例子在检索在zip文件中文件包的名字并且创建一个包含这些文件名称的文件文本。
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.
在本例中,try-with-resources语句包含两个用分号分隔的声明:ZipFile和BufferedWriter。当这块代码允许结束或者异常终止的时候,BufferedWriter和ZipFile对象的close方法将按以下顺序自动调用:注意,资源的close方法的调用顺序与它们的创建顺序相反。
The following example uses a try
-with-resources statement to automatically close a java.sql.Statement
object:
下面的示例使用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);
}
}
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.
在本例中使用的这个 java.sql.Statement 资源
是JDBC 4.1和以后的API的一部分。
注意:带有资源的try语句可以像一般的try语句一样具有catch和finally块。在try-with-resources语句中,任何catch或finally块都是在声明的资源被关闭后才会执行的。