Как в 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(). Вы можете реализовать его непоследовательно, и никто вам не скажет. Скорее всего, у вас будут проблемы во время выполнения.