1. 程式人生 > >try catch 資源自動釋放: AutoCloseable

try catch 資源自動釋放: AutoCloseable

我們在使用try catch  資源的的時候 常常忘記釋放資源,比如JDBC連線,那麼下邊講的AutoCloseable 就是解決這個問題:資源自動釋放。

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.

帶有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 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).

在上邊這個例子中,被宣告在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 the try statement completes normally or abruptly. The following example uses a finally block instead of a try-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 and close both throw exceptions, then the method readFirstLineFromFileWithFinallyBlock throws the exception thrown from the finallyblock; 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.

但是,在上邊例中,如果方法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塊都是在宣告的資源被關閉後才會執行的。