为什么AutoCloseable是Closeable的基本接口(反之亦然)?

时间:2013-10-24 17:24:30

标签: java api interface

据我所知,Closeable接口来自Java 1.5,而AutoCloseable是在Java 1.7中引入的。
我想要理解的是为什么Closeable 扩展 AutoCloseable,反之亦然? 这是因为向后依赖(无法更改Closeable接口),即需要AutoCloseable具有比Closeable更广泛的异常吗?或者我的逻辑是错的,它应该是那样的?

4 个答案:

答案 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的任何资源。