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

How is in Java the idempotence of the close() method of the Closeable interface ensured?

Closeable 接口在 Java 5 中引入,而 AutoCloseable 接口与 try-with-resources 语句一起出现在 Java 7 中。 Closeable 扩展(自 Java 7 起)Autocloseable 接口。

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 处的文档还是这本书?这两个接口哪个需要幂等性?

(2) 无论哪一个都需要幂等——我说的对吗 Java 实际上根本没有办法保证它是幂等的?如果是这样,close方法的"requirement"是幂等的,是程序员应该做的事情,但我永远无法确定使用该接口的人实际上确实做到了,对吧?在这种情况下,幂等性只是 oracle 的一个建议,对吗?

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

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