java - Java中如何保证Closeable接口(interface)的close()方法的幂等性?

标签 java oracle try-with-resources idempotent autocloseable

Closeable 接口(interface)是在 Java 5 中引入的,而 AutoCloseable 接口(interface)是在 Java 7 中与 try-with-resources 语句一起出现的。 Closeable 扩展了(从 Java 7 开始)Autocloseable接口(interface)。

OCA/OCP Java SE 7 - Programmer I & II Study Guide这本书的第 399 页上说:

What happends if we call the close() multiple time? It depends. For classes that implement AutoCloseable, the implementation is required to be idempotent. Which means you can call close() all day and nothing will happen the second time and beyond. [...] For classes that implement Closeable, there is no such guarantee.

所以根据本文,AutoCloseable 的实现需要是幂等的,而Closeable 的实现则不需要。现在,当我查看 AutoCloseable interface at docs.oracle.com 的文档时,它说:

Note that unlike the close method of Closeable, this close method is not required to be idempotent. In other words, calling this close method more than once may have some visible side effect, unlike Closeable.close which is required to have no effect if called more than once.

现在这与书中所写的相反。我有两个问题:

(1) 什么是正确的? docs.oracle.com 上的文档还是书?这两个接口(interface)中哪一个需要幂等性?

(2) 不管哪一个需要幂等——Java实际上根本没有办法确保它是幂等的,我说得对吗?如果是这样,close 方法的“要求”是幂等的,这是程序员 应该 做的事情,但我永远无法确定使用该接口(interface)的人确实做到了做对了?在这种情况下,幂等性只是预言机的一个建议,对吗?

最佳答案

  1. 来自 Oracle 的 Javadoc 是正确的。只是一个直觉 - AutoCloseable 对象用于 try(){}(所谓的 try with resources) block ,其中 close () 实际上是自动调用的,而且只调用一次;同时 Closeable 接口(interface)方法中的 close() 您总是手动调用它,您可以不小心调用它两次或使您的代码易于阅读。 此外 - Closeable 扩展了 AutoCloseable 并且它不应该使 AutoCloseable 中的 close() 方法的契约变弱,它只能添加需求。因此,当 AutoCloseable 要求 close() 是幂等的并且扩展接口(interface)取消此要求时的抽象情况将只是一个糟糕的设计。

  2. 是的,你的理解是对的。这只是程序员应该考虑的契约(Contract)。就像 equals()hashCode() 之间的合约一样。您可以以不一致的方式实现它,编译器或其他任何东西都不会为您标记它。该问题只会在运行时出现。

关于java - Java中如何保证Closeable接口(interface)的close()方法的幂等性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32425976/

相关文章:

java - JList 自定义选择行为 - 包括从单击的项目到列表末尾的所有内容

java - 本地 JDBC 连接成功,部署时相同代码失败

Java Try With Resources - 关闭资源的顺序

java - Swing worker : function get()

java - @VisibleForTesting 和@Deprecated int 单元测试之间的区别

sql - partition by/order by 是否暗示查询中的排序?

java - catch block 和资源关闭的真正工作顺序是什么?

java - Swing 按钮和 FillRect

oracle - 为什么在准备好的语句中使用 COLLECT() 时会得到 "ORA-00932: inconsistent datatypes: expected - got -"?