实现可关闭或实现自动关闭

我在学习 Java 的过程中,我找不到任何关于 implements Closeableimplements AutoCloseable接口的好的解释。

当我实现一个 interface Closeable时,我的 EclipseIDE 创建了一个方法 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 {




}
156040 次浏览

AutoCloseable (在 Java7中引入)使得使用 试用资源成语成为可能:

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,您的类的用户将感激。

在我看来,您似乎不太熟悉接口。在您发布的代码中,您不需要实现 AutoCloseable

如果您打算实现自己的 PrintWriter,那么您只需要(或应该)实现 CloseableAutoCloseablePrintWriter处理需要关闭的文件或任何其他资源。

在您的实现中,调用 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) {
}
}
}

上面的代码是与 Java6相关的,在 Java7中可以做得更好(参见 这个答案)。

Closeable扩展了 AutoCloseable ,专门用于 IO 流: 它抛出 IOException而不是 Exception,并且是幂等的,而 AutoCloseable不提供这种保证。

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

实现 AutoCloseable(或 Closeable)允许一个类被用作 Java 7中引入的 尝试使用资源构造的资源,它允许在一个块的末尾自动关闭这些资源,而不必添加一个显式关闭资源的 finally块。

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

下面是一个小例子

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

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 关键字之后出现在括号内。JavaSE7及更高版本中的类 BufferedReader实现了接口 java.lang.AutoCloseable。因为 BufferedReader实例是在 try-with-resource 语句中声明的,所以无论 try 语句是正常完成还是突然完成(由于方法 BufferedReader.readLine抛出了 IOException) ,它都将被关闭。

在 JavaSE7之前,可以使用 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();
}


}

请参阅文件

最近我读了一本 JavaSE8程序员指南。

我发现了 AutoCloseableCloseable的区别。

AutoCloseable接口是在 Java7中引入的 它类似于语言设计者想要的 下列例外情况:

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

语言设计者强调向下兼容 接口是不可取的,他们做了一个新的称为 AutoCloseable。这个新的 接口没有 Closeable严格。由于 Closeable满足 当引入 AutoCloseable时,它开始实现 AutoCloseable