¿Cómo se garantiza en Java la idempotencia del método close() de la interfaz Closeable?
oracle try-with-resources (1)
Javadoc de Oracle es correcto. Solo una intuición de por qué: los objetos que se pueden cerrar automáticamente se usan en los bloques
try(){}
, donde en realidad se llama a close automáticamente y solo una vez; al mismo tiempo,close()
del método de interfazCloseable
, usted siempre llama manualmente y puede llamarlo accidentalmente o para que su código sea fácil de leer. Además,Closeable
extiendeAutoCloseable
y no pudo debilitar el método declose()
declose()
deAutoCloseable
, solo puede agregar requisitos. Por lo tanto, una situación abstracta cuandoAutoCloseable
requería queclose()
fuera idempotente y la interfaz extendida cancelara este requisito sería solo un mal diseño.Sí, tu entendimiento es correcto. Es solo un contrato que el programador debe tener en cuenta. Al igual que el contrato entre
equals()
yhashCode()
. Puedes implementarlo de forma inconsistente y nadie te lo dirá. Es muy probable que tengas problemas en el tiempo de ejecución.
La interfaz Closeable
se introdujo en Java 5, mientras que la interfaz AutoCloseable
presentó en Java 7 junto con la declaración try-with-resources
. Closeable
extiende (desde Java 7) la interfaz de Autocloseable
.
En el libro OCA / OCP Java SE 7 - Programmer I & II Guía de estudio que dice en la página 399:
¿Qué pasa si llamamos el
close()
varias veces? Depende. Para las clases que implementanAutoCloseable
, se requiere que la implementación sea idempotente. Lo que significa que puede llamar aclose()
todo el día y nada pasará la segunda vez y más allá. [...] Para las clases que implementanCloseable
, no existe tal garantía.
Así que de acuerdo con este texto, las implementaciones de AutoCloseable
deben ser idempotentes, y las de Closeable
no. Ahora, cuando veo la documentación de la interfaz de AutoCloseable
en docs.oracle.com , dice:
Tenga en cuenta que, a diferencia del método de
close
deCloseable
, este método de cierre no tiene que ser idempotente. En otras palabras, llamar a este método declose
más de una vez puede tener algún efecto secundario visible, a diferencia deCloseable.close
que se requiere que no tenga efecto si se llama más de una vez.
Ahora esto es lo opuesto a lo que está escrito en el libro. Tengo dos preguntas:
(1) ¿Qué es correcto? ¿El documento en docs.oracle.com o el libro? ¿Cuál de las dos interfaces requiere idempotencia?
(2) No importa cuál sea el idempotente, ¿tengo razón en que Java no tiene ninguna forma de garantizar que sea idempotente? Si es así, el "requisito" del método de close
para ser idempotente es algo que debe hacer el programador, pero nunca puedo estar seguro de que alguien que usó la interfaz realmente lo hizo, ¿verdad? En este caso, la idempotencia es simplemente una sugerencia de oráculo, ¿correcto?