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