据我所知,Closeable接口来自Java 1.5,而AutoCloseable是在Java 1.7中引入的。
我想要理解的是为什么Closeable 扩展 AutoCloseable,反之亦然?
这是因为向后依赖(无法更改Closeable接口),即需要AutoCloseable具有比Closeable更广泛的异常吗?或者我的逻辑是错的,它应该是那样的?
答案 0 :(得分:30)
这样,实现Closeable
的所有用户代码都会自动实现AutoCloseable
,这样他们就可以自动从try-with-resources语法中受益。
答案 1 :(得分:22)
@Sotirios Delimanolis的评论已经确定了它。
Java 7团队想要一种机制来将对象标记为“try with resources”构造可自动关闭。不幸的是,Closeable.close()
方法的API规范过于严格。它要求close()
方法是幂等的......但在“尝试使用资源”用例中这不是必需的。
因此,他们将AutoClosable
界面引入了限制性较小的close()
语义...并且改编为Closeable
作为AutoCloseable
的子类型。
另一件事是AutoCloseable.close()
被宣布为投掷Exception
而不是IOException
。这意味着AutoCloseable
API的限制性低于Closeable
...并且考虑到它在try-with-resources中被有效地用作回调 API,这使得它成为可能更灵活/更广泛适用。 (API可用于与I / O无关的资源,但仍可能在关闭时抛出异常。)另一方面,如果{{1} {Java},Java类型将不允许它们进行此类更改。 }方法已注入子类型。
替代方案应该是:
将“尝试使用资源”限制为具有幂等关闭的资源...这限制了其有用性,或者
回顾性地改变closes() throws Exception
的语义...这可能导致将旧代码移植到Java 7的困难
回顾性地更改了Closeable.close()
的签名......这将破坏二进制兼容性。
答案 2 :(得分:1)
{5}中引入了Closeable
接口。
当在Java 7中引入try-with-resources
(下面是一个示例代码)时,语言设计者想要改变一些东西但需要向后兼容性(所有以前版本中编写的代码都不应该因为引入新功能而过时)所以他们用他们想要的规则创建了一个超级接口AutoCloseable
。
尝试使用资源的示例:
try (NewResource a = NewResource.CreateResource();
{
}
以上代码是试用资源。我们可以简单地理解,在这段代码中,我们可以在try代码中声明一个新变量,该变量可以调用代码中的其他方法。除了减少try
块的详细程度之外,此代码也不需要finally块,但执行环境应该是Java 7或更高版本。虽然最终是由JVM自己创建的。
closeable
& Autocloseable
接口只包含一个方法
void close()
虽然close ()
closeable
方法引发了IOException
,但Autocloseable
close()
方法会引发Exception
。
答案 3 :(得分:0)
Closeable
有一些限制,因为它只能抛出IOException
,所以如果不破坏遗留代码就无法更改它。
因此引入了AutoCloseable
,可以抛出Exception
。
AutoCloseable
将用于使用> JDK7的应用程序。
由于JDK7 +库使用AutoCloseable
,实现Closeable
的遗留代码仍然需要与JDK7 +兼容,
使得Closeable扩展AutoCloseable。
public interface Closeable extends AutoCloseable {
public void close() throws IOException;
}
AutoCloseable
专门用于处理try-with-resources语句。
当Closeable
扩展AutoCloseable
时,可以使用try-with-resources关闭实现Closeable或AutoCloseable的任何资源。