Java SE7新特性之try-with-resources語句
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
, 或者沒有異常。
本文翻譯自Oracle官方文件http://docs.oracle.com/javase/7/docs/technotes/guides/language/try-with-resources.html,如有不正確的地方,敬請指正,謝謝!
from: https://blog.csdn.net/jackiehff/article/details/17765909