简体   繁体   English

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

[英]Why is AutoCloseable the base interface for Closeable (and not vice versa)?

As far as I know, the Closeable interface was around from Java 1.5 and the AutoCloseable was introduced in Java 1.7.据我所知, Closeable接口是从 Java 1.5 开始的,而AutoCloseable是在 Java 1.7 中引入的。
What I am trying to understand is why Closeable extends AutoCloseable and not vice versa?我想了解的是为什么 Closeable扩展AutoCloseable 而不是反之亦然? Is this done because of backward dependency (not being able to change the Closeable interface) ie the need for AutoCloseable to have a wider exception than Closeable?这样做是否因为向后依赖(无法更改 Closeable 接口),即 AutoCloseable 需要比 Closeable 具有更广泛的异常? Or is my logic just wrong and it should be that way?还是我的逻辑错了,应该是这样?

这样,所有实现Closeable的用户代码Closeable自动实现AutoCloseable ,这允许他们自动从 try-with-resources 语法中受益。

@Sotirios Delimanolis's comment has nailed it. @Sotirios Delimanolis 的评论已经说明了这一点。

The Java 7 team wanted a mechanism to label objects as be auto-closeable for the "try with resources" construct. Java 7 团队想要一种机制来标记对象为“尝试使用资源”构造可自动关闭。 Unfortunately the API spec for the Closeable.close() method is too strict.不幸的是Closeable.close()方法的 API 规范太严格了。 It requires the close() method to be idempotent ... but this is not necessary in the "try with resources" use-case.它要求close()方法是幂等的……但这在“尝试资源”用例中不是必需的。

So they introduced the AutoClosable interface with a less restrictive close() semantic ... and retro-fitted Closeable as a subtype of AutoCloseable .因此,他们引入了AutoClosable接口,其具有较少限制的close()语义......并改装Closeable作为AutoCloseable的子类型。

The other thing is that AutoCloseable.close() is declared as throwing Exception rather than IOException .另一件事是AutoCloseable.close()被声明为抛出Exception而不是IOException This means that the AutoCloseable API is less restrictive than Closeable ... and given that it is effectively used as a callback API in try-with-resources, this makes it more flexible / more broadly applicable.这意味着AutoCloseable API 比Closeable限制Closeable ......并且鉴于它在 try-with-resources 中有效用作回调API,这使其更灵活/更广泛适用。 (The API can be used for resources that have nothing to do with I/O, but still might throw exceptions on close.) The flip-side is that Java typing would not allow them to make such a change if the close() throws Exception method had been injected into the subtype. (API 可用于与 I/O 无关的资源,但仍可能在关闭时抛出异常。)另一方面,如果close() throws Exception ,Java 类型将不允许它们进行此类更改close() throws Exception方法已被注入到子类型中。


The alternatives would have been:替代方案是:

  • to restrict "try with resources" to resources with an idempotent close ... which limits its usefulness, or将“尝试资源”限制为具有幂等关闭的资源......这限制了其有用性,或

  • to retrospectively change the semantics of Closeable.close() ... which could lead to difficulties for folks porting older code to Java 7回顾性地更改Closeable.close()的语义......这可能会导致人们难以将旧代码移植到 Java 7

  • to retrospectively change the signature of Closeable.close() ... which would break binary compatibility.追溯更改Closeable.close()的签名......这会破坏二进制兼容性。

The Closeable interface was introduced in Java 5. When try-with-resources (below is an example code) was introduced in Java 7, the language designers wanted to change some things but needed backward compatibility (all the code which is written in previous versions should not become obsolete with introduction of new functionalities) also so they created a Superinterface AutoCloseable with the rules they wanted. Closeable接口是在 Java 5 中引入的。 当try-with-resources (下面是示例代码)在 Java 7 中引入时,语言设计者想要改变一些东西但需要向后兼容(所有代码都是在以前的版本中编写的不应该随着新功能的引入而过时),因此他们创建了一个带有他们想要的规则的 Superinterface AutoCloseable

An example of try with resources:尝试使用资源的示例:

    try (NewResource a = NewResource.CreateResource();
{
    }

Above code is Try with resources.上面的代码是尝试使用资源。 We can simply understand by this is that in this code we can declare a new variable itself in the try code and that variable can call upon other methods within the code.我们可以简单地理解为,在这段代码中,我们可以在 try 代码中声明一个新变量本身,并且该变量可以调用代码中的其他方法。 Apart from decreasing verbosity of try block this code also does not require a finally block, but the executing environment should be Java 7 or above.除了减少try块的冗长之外,这段代码也不需要 finally 块,但执行环境应该是 Java 7 或更高版本。 Although the finally is created by JVM itself.虽然finally是JVM自己创建的。

closeable & Autocloseable interface contains just one method closeableAutocloseable接口只包含一个方法

void close()

While close () method of closeable throws IOException , Autocloseable 's close() method throws Exception .close ()的方法closeable抛出IOExceptionAutocloseableclose()方法将抛出Exception

Closeable has some limitations, as it can only throw IOException , so it cannot be changed without breaking legacy code. Closeable有一些限制,因为它只能抛出IOException ,因此在不破坏遗留代码的情况下无法更改它。 So AutoCloseable was introduced, which can throw Exception .所以引入了AutoCloseable ,它可以抛出Exception

AutoCloseable is to be used for applications using >JDK7. AutoCloseable用于使用 >JDK7 的应用程序。

As JDK7+ libraries use AutoCloseable and legacy code which implements Closeable still need to be compatible with JDK7+, it is made that Closeable extend AutoCloseable.由于 JDK7+ 库使用AutoCloseable并且实现Closeable遗留代码仍然需要与 JDK7+ 兼容,因此 Closeable 扩展了 AutoCloseable。

public interface Closeable extends AutoCloseable {
    public void close() throws IOException;
}

AutoCloseable was specifically designed to work with try-with-resources statements. AutoCloseable专门设计用于与 try-with-resources 语句一起使用。 As Closeable extends AutoCloseable , try-with-resources can be used to close any resources that implement either Closeable or AutoCloseable.由于Closeable扩展了AutoCloseable ,try-with-resources 可用于关闭任何实现 Closeable 或 AutoCloseable 的资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM