Как в Java обеспечивается идемпотенция метода close() закрываемого интерфейса?
на Closeable
интерфейс был введен в Java 5, тогда как AutoCloseable
интерфейс пришел в Java 7 вместе с try-with-resources
заявление. Closeable
расширяет (начиная с Java 7)Autocloseable
интерфейс.
в книге OCA / OCP Java SE 7-программист I & II учебное пособие на странице 399 написано:
что произойдет, если мы назовем
close()
несколько раз? Это зависит от. Для классов, реализующихAutoCloseable
реализация должна быть идемпотентный. Это означает, что вы можете позвонитьclose()
весь день и ничего не произойдет во второй раз и за его пределами. [...] Для классов, реализующихCloseable
, нет такой гарантии.
Итак, согласно этому тексту, реализаций AutoCloseable
должны быть идемпотентными, и Closeable
нет. Теперь, когда я взгляну на документацию AutoCloseable
интерфейс на docs.oracle.com, он говорит:
обратите внимание, что в отличие от
close
способ изCloseable
, этот метод close не обязательно должен быть идемпотентным. Другими словами, называя этоclose
метод более одного раза может иметь видимый побочный эффект, в отличие отCloseable.close
который не должен иметь никакого эффекта, если вызывается более одного раза.
теперь это противоположно тому, что написано в книге. У меня два вопроса:--18-->
(1) что правильно? The doc at docs.oracle.com или книгу? Какой из двух интерфейсов требует idempotence?
(2) независимо от того, какой из них должен быть идемпотентным - я прав, что Java фактически не имеет никакого способа гарантировать, что он идемпотентен? Если да, то "требование"close
метод быть идемпотентным-это то, что программист должны do, но я никогда не могу быть уверен, что кто-то, кто использовал интерфейс, действительно сделал это, верно? В этом случае идемпотенция - это просто предложение оракула, верно?
1 ответов
Javadoc из Oracle является правильным. Просто интуиция, почему ... --0--> объекты используются в
try(){}
блоки, где close фактически вызывается автоматически и только один раз; в то же времяclose()
СCloseable
метод интерфейса вы всегда вызываете вручную, и вы можете вызвать его дважды случайно или сделать ваш код легко читаемым. Кроме того -Closeable
выходитAutoCloseable
и это не могло ослабить контрактclose()
методAutoCloseable
- Он может только добавлять требования. Итак, аннотация ситуация, когдаAutoCloseable
требуютсяclose()
чтобы быть идемпотентным и расширенным интерфейсом, это требование было бы просто плохим дизайном.Да, ваше понимание является правильным. Это просто контракт, который программист должен принять во внимание. Как договор между
equals()
иhashCode()
. Вы можете реализовать его непоследовательно, и никто вам не скажет. Скорее всего, у вас будут проблемы во время выполнения.