我正在学习Java,但在implements Closeable
和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 {
}
答案 0 :(得分:158)
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 res here
}
并且JVM会自动为您调用close()
。 Closeable
是一个较旧的界面。 由于某种原因为了保持向后兼容性,语言设计者决定创建一个单独的兼容性。这不仅可以在try-with-resources中使用所有Closeable
类(如抛出IOException
的流),还可以从close()
中抛出更多常规检查异常。
如果有疑问,请使用AutoCloseable
,您班上的用户将不胜感激。
答案 1 :(得分:62)
Closeable
扩展AutoCloseable
,专门用于IO流:它抛出IOException而不是Exception,并且是幂等的,而AutoCloseable不提供此保证。
这两个接口的javadoc都解释了这一点。
实现AutoCloseable(或Closeable)允许将一个类用作Java 7中引入的try-with-resources构造的资源,该构造允许在块结束时自动关闭这些资源,而不必添加最终明确关闭资源的块。
您的类不代表可关闭的资源,并且实现此接口绝对没有意义:无法关闭IOTest。它甚至不可能实例化它,因为它没有任何实例方法。请记住,实现接口意味着类和接口之间存在 is-a 关系。你在这里没有这样的关系。
答案 2 :(得分:31)
在我看来,你对界面不是很熟悉。在您发布的代码中,您无需实施AutoCloseable
。
如果您要实施自己的PrintWriter
来处理文件或需要关闭的任何其他资源,您只需(或应该)实施Closeable
或AutoCloseable
。
在您的实施中,只需拨打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中,这可以更优雅地完成(参见this answer)。
答案 3 :(得分:6)
这是一个小例子
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
答案 4 :(得分:5)
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
抛出{{1}的结果,它都将被关闭}})。
在Java SE 7之前,您可以使用IOException
块来确保资源被关闭,无论try语句是正常还是突然完成。以下示例使用finally
块而不是finally
语句:
try-with-resources
答案 5 :(得分:1)
最近我已经阅读了Java SE 8程序员指南ii。
我发现了AutoCloseable与Closeable之间的区别。
Java 7中引入了AutoCloseable接口。在此之前,另一个接口 存在称为“可关闭”。它类似于语言设计师想要的, 以下例外:
语言设计师强调向后兼容性。由于改变了现有的 界面是不可取的,他们做了一个新的叫做AutoCloseable的界面。这个新的 界面不如Closeable严格。由于Closeable符合以下要求 AutoCloseable,它在引入AutoCloseable后就开始实现。