Как должен вести себя закрытый ресурс в java? - PullRequest
7 голосов
/ 15 апреля 2020

У меня есть класс java, который содержит закрываемый ресурс внутри. Это означает, что мой класс также реализует интерфейс Closeable и закрывает внутренний ресурс в своем собственном методе close ().

Каково ожидаемое поведение моего класса после того, как он был закрыт, и обычно любой закрытый объект в Java? Я вижу объект в несуществующем состоянии, где его внутренности закрыты, но клиенты все еще имеют ссылку на него. Доступ IMO к нему - ошибка программирования, но ошибки случаются время от времени, поэтому поведение должно быть разумным даже в этом случае ...

Должен ли я?

  • бросить исключение для всех вызовы методов, такие как: IllegalState
  • закрыть глаза, как будто ничего не произошло, и пропустить исключения из ресурса закрытия?

Что такое канонический Java способ?

Ответы [ 3 ]

5 голосов
/ 15 апреля 2020

Вы должны выдать исключение при попытке доступа к внутреннему ресурсу после его закрытия, исключение IllegalStateException. Стоит отметить, что вы можете использовать свой Closeable в попытке с ресурсами, чтобы в дальнейшем гарантировать, что после того, как объект выпадет из области видимости, он будет закрыт.

4 голосов
/ 15 апреля 2020

Что такое канонический Java способ?

Сначала давайте рассмотрим javado c метода close():

Закрывает этот поток и освобождает все системные ресурсы, связанные с ним. Если поток уже закрыт, то вызов этого метода не имеет никакого эффекта.

Таким образом, ответ на ваш вариант «ни один из вышеперечисленных» для метода close(). Вы не выбрасываете исключение и не пропускаете исключения из закрытого ресурса. Если он был закрыт, вызов должен быть N OOP.

Теперь давайте посмотрим на некоторые из Closeable классов:

  • FileInputStream.read()

    Броски IOException при возникновении ошибки ввода-вывода.

    Это включает в себя «файл закрыт».

    Это относится ко всем классам ввода / вывода InputStream / OutputStream / Reader / Writer.

  • FileSystem.close()

    После того, как файловая система закрыта, затем весь последующий доступ к файловой системе, либо методами, определенными этим классом, либо объектами, связанными с этой файловой системой, выдает ClosedFileSystemException. Если файловая система уже закрыта, то вызов этого метода не имеет никакого эффекта.

  • Formatter.close()

    Попытка вызов любых методов, кроме ioException() в этом форматере, после его закрытия приведет к FormatterClosedException.

  • URLClassLoader.findClass(name)

    Броски ClassNotFoundException, если класс не найден или загрузчик закрыт.

Вывод: Все методы (кроме close()) генерируют исключения, но не IllegalStateException.

Конечно, вы можете использовать IllegalStateException, если вы хочу.

2 голосов
/ 15 апреля 2020

Просто взгляните на один из наиболее часто используемых интерфейсов с методом close, java.sql.Connection:

Здесь выдается исключение:

SQLException if a database access error occurs or this method is called on a closed connection

Это в основном то, что имеет смысл: при вызове метода close разработчик охотно закрывает любой объект (Connection, Socket, Stream, ...) и, следовательно, оставляет это, как вы уже заявили, в несуществующем состоянии. Если сейчас разработчик пытается вызвать какую-то функцию для закрытого объекта, он должен получить ошибку, поэтому единственное правильное действие, которое необходимо сделать здесь, - это исключение.

...