155

implements Closeable我正在学习 Java,但在接口和implements AutoCloseable接口上找不到任何好的解释。

当我实现了一个方法时interface Closeable,我的 Eclipse IDE 创建了一个方法public void close() throws IOException

我可以在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 {


}
4

6 回答 6

217

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类(如流 throwing IOException),还允许从close().

如有疑问,请使用AutoCloseable,您班级的用户将不胜感激。

于 2012-10-30T14:41:17.923 回答
86

CloseableextendsAutoCloseable,并且专门用于 IO 流:它抛出IOException而不是Exception,并且是幂等的,AutoCloseable而不提供此保证。

这在两个接口的 javadoc 中都有解释。

实现AutoCloseable(或Closeable)允许将类用作 Java 7 中引入的try-with-resources构造的资源,这允许在块末尾自动关闭此类资源,而无需添加finally显式关闭资源的块.

您的类不代表可关闭的资源,实现此接口绝对没有意义:IOTest无法关闭。甚至不可能实例化它,因为它没有任何实例方法。请记住,实现接口意味着类和接口之间存在一种关系。你在这里没有这样的关系。

于 2012-10-30T14:46:18.113 回答
46

在我看来,您对接口不是很熟悉。在您发布的代码中,您不需要实现AutoCloseable.

您只需要(或应该)实现Closeable,或者AutoCloseable如果您即将实现自己的PrintWriter,它处理文件或任何其他需要关闭的资源。

在您的实现中,调用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 中,这可以更优雅地完成(参见这个答案)。

于 2012-10-30T14:45:03.480 回答
8

这是一个小例子

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
于 2017-03-17T12:12:00.907 回答
8

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

AutoCloseable我发现了一些关于vs之间的区别Closeable

AutoCloseable接口是在 Java 7 中引入的。在此之前,存在另一个接口,称为Closeable. 它与语言设计者想要的类似,但有以下例外:

  • Closeable将抛出的异常类型限制为IOException.
  • Closeable要求实现是幂等的。

语言设计者强调向后兼容性。由于不希望更改现有接口,因此他们制作了一个名为AutoCloseable. 这个新接口没有Closeable. 由于Closeable符合 的要求 ,所以在引入后者时AutoCloseable就开始实施。AutoCloseable

于 2018-07-25T14:02:36.487 回答
7

try-with-resources声明。

Thetry-with-resources statementtry声明一个或多个资源的语句。Aresource是一个在程序完成后必须关闭的对象。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();
    }

}

参阅文档

于 2017-05-09T11:22:27.327 回答