【问题标题】:How should a closed resource behave in java?java中封闭的资源应该如何表现?
【发布时间】:2020-07-28 11:19:29
【问题描述】:

我有一个 Java 类,它在内部拥有一个 Closeable 资源。这意味着我的类也实现了 Closeable 接口,并在其自己的 close() 方法中关闭了内部资源。

我的类被关闭之后的预期行为是什么,通常是 Java 中的任何关闭对象?我看到该对象处于失效状态,其内部已关闭,但客户端仍对其有引用。 IMO 访问它是一个编程错误,但错误时有发生,所以即使在这种情况下,行为也应该是合理的......

我应该吗?

  • 对所有方法调用抛出异常,例如:IllegalState
  • 闭上眼睛就像什么都没发生一样让异常从关闭的资源中通过?

什么是规范的Java方式?

【问题讨论】:

  • IllegalStateException 是合适的。除了,大多数可关闭资源允许多次调用 close() 而不会产生异常。

标签: java autocloseable


【解决方案1】:

当试图访问内部资源被关闭后,你应该抛出一个异常,一个 IllegalStateException 就可以了。值得注意的一件事是,您可以在 try-with-resources 中使用 Closeable,以进一步确保一旦对象超出范围,它就会关闭。

【讨论】:

    【解决方案2】:

    看看一个可能最常用的带有 close 方法的接口之一,java.sql.Connection

    这里抛出异常:

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

    这基本上是有意义的:如果调用close 方法,开发人员愿意 关闭任何对象(ConnectionSocketStream,...)因此,正如您已经说过的那样,它处于失效状态。如果开发人员现在尝试在关闭的对象上调用某个函数,他应该会得到一个错误,因此这里唯一正确的做法是异常。

    【讨论】:

      【解决方案3】:

      什么是规范的Java方式?

      首先,我们看一下close()方法的javadoc:

      关闭此流并释放与其关联的所有系统资源。 如果流已经关闭,则调用此方法无效。

      因此,对于close() 方法,您的选项的答案是“以上都不是”。您不会抛出异常,也不会让已关闭资源的异常通过。如果已关闭,则调用必须为 NOOP。

      现在,让我们看一下Closeable 的一些类:

      • FileInputStream.read()

        如果发生 I/O 错误,则抛出 IOException

        这包括“文件关闭”。

        这适用于所有 InputStream/OutputStream/Reader/Writer I/O 类。

      • FileSystem.close()

        在文件系统关闭后,随后对文件系统的所有访问,无论是通过此类定义的方法还是在与此文件系统关联的对象上,都抛出 ClosedFileSystemException。如果文件系统已经关闭,则调用此方法无效。

      • Formatter.close()

        在此格式化程序关闭后尝试在此格式化程序中调用除ioException() 之外的任何方法将导致FormatterClosedException

      • URLClassLoader.findClass(name)

        如果找不到类或加载器已关闭,则抛出 ClassNotFoundException

      结论:所有方法(close() 除外)都会抛出异常,但 IllegalStateException 除外。

      如果你愿意,当然可以使用IllegalStateException

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-17
        • 2011-07-25
        • 2019-08-18
        • 1970-01-01
        • 2011-03-03
        • 1970-01-01
        相关资源
        最近更新 更多