25

The Closeable interface was introduced in Java 5 whereas the AutoCloseable interface came in Java 7 together with the try-with-resources statement. Closeable extends (since Java 7) the Autocloseableinterface.

In the book OCA/OCP Java SE 7 - Programmer I & II Study Guide it says on page 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.

So according to this text, implementations of AutoCloseable need to be idempotent, and those of Closeable not. Now when I have a look at the documentation of the AutoCloseable interface at docs.oracle.com, it says:

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.

Now this is the opposite of what is written in the book. I have two questions:

(1) What is correct? The doc at docs.oracle.com or the book? Which of the two interfaces requires idempotence?

(2) No matter which one needs to be idempotent - am I right that Java has actually no way at all to ensure that it is idempotent? If so, the "requirement" of the close method to be idempotent is something that the programmer should do, but I can never be sure that someone who used the interface actually did do it, right? In this case the idempotence is merely a suggestion of oracle, correct?

Mathias Bader
  • 3,585
  • 7
  • 39
  • 61
  • 2) What do you mean by: "Java has actually no way at all to ensure that it is idempotent". The language does, such as having final boolean flag indicating method is called. On the other hand, compiler does not do some kind of validation of close implementation to verify that implementation is idempotent. – John Sep 06 '15 at 17:03
  • 3
    About (1): The book actually has a mistake here, just found the errata on this page where it is mentioned: http://www.coderanch.com/t/641206/ocajp/certification/Errata-OCA-OCP-Java-SE – Mathias Bader Sep 06 '15 at 17:05
  • @John: I do not understand what you mean with the boolean flag. I am solely talking about the idempotence property here. My guess is that a validation of the idempotence property is not performed and even that is would not be possible to do this. – Mathias Bader Sep 06 '15 at 17:07
  • The first sentence in question 2 kind of suggests that it is impossible to implement idempotent method in java. Well about it being impossible, i wouldn't go that far with that. There is no such check however. – John Sep 06 '15 at 17:10
  • @John: I see what you mean. No I don't want to say that it is impossible to implement. I want to say that it is impossible **to check** that it is actually idempotent. – Mathias Bader Sep 06 '15 at 17:11
  • 1
    It would be strange if `AutoCloseable` required `close()` to be idempotent and `Closeable`, a subtype, did not. That would imply that there could be `AutoCloseable`s without an idempotent `close()`, as long as they implement `Closeable` at the same time… – Holger Sep 29 '15 at 17:29

1 Answers1

21
  1. Javadoc from Oracle is correct. Just an intuition why - AutoCloseable objects are used in try(){} (so called try with resources) blocks, where close() is actually called automatically and only once; at the same time close() from Closeable interface method you always call manually and you can call it twice accidentally or to make your code easy to read. In addition - Closeable extends AutoCloseable and it shouldn't make the contract of close() method from AutoCloseable weaker, it can only add requirements. So, an abstract situation when AutoCloseable required close() to be idempotent and extended interface canceled this requirement would be just a bad design.

  2. Yes, your understanding is right. It's just a contract that a programmer should take into account. Like the contract between equals() and hashCode(). You can implement it in an inconsistent way and a compiler or anything else will not flag it for you. The problem will materialize only in runtime.

Dmitry Spikhalskiy
  • 5,379
  • 1
  • 26
  • 40
  • 2
    I like the comparison with `equals()` and `hashCode()` - that's a good one. – Mathias Bader Sep 06 '15 at 17:08
  • Well it is a _bit_ more than something a programmer should do - it is also a promise that the JAVA APIs themselves (written by the same group that wrote `Closeable`) will implement `close()` to be idempotent. Of course, if you implement `close()` yourself, noone can force you to make it idempotent. – sleske Oct 30 '18 at 14:58