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

该接口是在Java 5中引入的,而该接口与语句一起在Java 7中引入。 扩展(从Java 7开始)接口。CloseableAutoCloseabletry-with-resourcesCloseableAutocloseable

OCA / OCP Java SE 7 - Programmer I & II Study Guide一书中,它在第399页说:

如果我们调用多次时间会发生什么?这要视情况而定。对于实现的类,实现必须是幂等的。这意味着您可以整天打电话,第二次及以后不会发生任何事情。[...]对于实现的类,没有这样的保证。close()AutoCloseableclose()Closeable

因此,根据此文本,的实现需要是幂等的,而那些不是。现在,当我在 docs.oracle.com 查看自动关闭界面的文档时,它说:AutoCloseableCloseable

请注意,与 的方法不同,这个接近方法不需要是幂等的。换句话说,多次调用此方法可能会产生一些明显的副作用,这与多次调用时不需要任何效果的副作用不同。closeCloseablecloseCloseable.close

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

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

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


答案 1
  1. 来自Oracle的Javadoc是正确的。只是一个直觉为什么 - 对象用于(所谓的尝试资源)块,其中实际上被自动调用并且只调用一次;同时从接口方法,你总是手动调用,你可以意外地调用它两次,或者让你的代码易于阅读。此外 - 扩展,它不应该使方法的契约从弱,它只能添加需求。因此,当需要幂等且扩展接口取消此要求时,抽象的情况将只是一个糟糕的设计。AutoCloseabletry(){}close()close()CloseableCloseableAutoCloseableclose()AutoCloseableAutoCloseableclose()

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


答案 2

推荐