try catch 資源自動釋放: AutoCloseable
我們在使用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塊都是在宣告的資源被關閉後才會執行的。