簡體   English   中英

實現 Closeable 或實現 AutoCloseable

[英]implements Closeable or implements AutoCloseable

我正在學習 Java,我找不到關於implements Closeableimplements AutoCloseable接口的任何好的解釋。

當我實現一個interface Closeable ,我的 Eclipse IDE 創建了一個方法public void close() throws IOException

我可以使用pw.close();關閉流pw.close(); 沒有接口。 但是,我無法理解如何使用該接口實現close()方法。 而且,這個接口的目的是什么?

我也想知道:如何檢查IOstream是否真的關閉了?

我正在使用下面的基本代碼

import java.io.*;

public class IOtest implements AutoCloseable {

public static void main(String[] args) throws IOException  {

    File file = new File("C:\\test.txt");
    PrintWriter pw = new PrintWriter(file);

    System.out.println("file has been created");

    pw.println("file has been created");

}

@Override
public void close() throws IOException {


}

AutoCloseable (在 Java 7 中引入)使得使用try-with-resources習語成為可能:

public class MyResource implements AutoCloseable {

    public void close() throws Exception {
        System.out.println("Closing!");
    }

}

現在你可以說:

try (MyResource res = new MyResource()) {
    // use resource here
}

JVM 會自動為你調用close()

Closeable是一個較舊的界面。 因為某些原因為了保持向后兼容性,語言設計者決定創建一個單獨的。 這不僅允許在 try-with-resources 中使用所有Closeable類(如拋出IOException流),還允許從close()拋出更一般的檢查異常。

如有疑問,請使用AutoCloseable ,您班級的用戶將不勝感激。

Closeable擴展了AutoCloseable ,並且專門用於 IO 流:它拋出IOException而不是Exception ,並且是冪等的,而AutoCloseable不提供這種保證。

這在兩個接口的 javadoc 中都有解釋。

實現AutoCloseable (或Closeable )允許將類用作 Java 7 中引入的try-with-resources構造的資源,這允許在塊的末尾自動關閉此類資源,而無需添加用於關閉的finally塊資源明確。

你的類不代表一個可關閉的資源,實現這個接口絕對沒有意義:一個IOTest不能被關閉。 甚至不應該實例化它,因為它沒有任何實例方法。 請記住,實現接口意味着類和接口之間存在 is -a關系。 你在這里沒有這種關系。

在我看來,您對接口不是很熟悉。 在您發布的代碼中,您不需要實現AutoCloseable

如果您要實現自己的PrintWriter ,則只需(或應該)實現CloseableAutoCloseable ,它處理需要關閉的文件或任何其他資源。

在您的實現中,調用pw.close()就足夠了。 您應該在 finally 塊中執行此操作:

PrintWriter pw = null;
try {
   File file = new File("C:\\test.txt");
   pw = new PrintWriter(file);
} catch (IOException e) {
   System.out.println("bad things happen");
} finally {
   if (pw != null) {
      try {
         pw.close();
      } catch (IOException e) {
      }
   }
}

上面的代碼是 Java 6 相關的。 在 Java 7 中,這可以更優雅地完成(請參閱此答案)。

這是一個小例子

public class TryWithResource {

    public static void main(String[] args) {
        try (TestMe r = new TestMe()) {
            r.generalTest();
        } catch(Exception e) {
            System.out.println("From Exception Block");
        } finally {
            System.out.println("From Final Block");
        }
    }
}



public class TestMe implements AutoCloseable {

    @Override
    public void close() throws Exception {
        System.out.println(" From Close -  AutoCloseable  ");
    }

    public void generalTest() {
        System.out.println(" GeneralTest ");
    }
}

這是輸出:

GeneralTest 
From Close -  AutoCloseable  
From Final Block

最近我讀了一本 Java SE 8 Programmer Guide ii Book。

我發現了AutoCloseableCloseable之間的區別。

AutoCloseable接口是在 Java 7 中引入的。在此之前,存在另一個名為Closeable接口。 它類似於語言設計者想要的,但有以下例外:

  • Closeable將拋出的異常類型限制為IOException
  • Closeable要求實現是冪等的。

語言設計者強調向后兼容性。 由於更改現有界面是不可取的,因此他們創建了一個名為AutoCloseable的新界面。 這個新接口沒有Closeable嚴格。 由於Closeable滿足AutoCloseable的要求,因此在引入AutoCloseable時它開始實現AutoCloseable

try-with-resources聲明。

try-with-resources statement是一種聲明一個或多個資源的try語句。 resource是程序完成后必須關閉的對象。 try-with-resources statement確保每個資源在語句結束時關閉。 任何實現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 ),它都會被關閉。

在 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();
    }

}

參閱文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM