【问题标题】:Why close method of java.lang.AutoCloseable throws Exception, but close method of java.io.Closeable throws IOException?为什么java.lang.AutoCloseable的close方法抛出异常,而java.io.Closeable的close方法抛出IOException?
【发布时间】:2014-11-15 13:48:01
【问题描述】:

我正在为try-with-resources 阅读此link,它说:

Closeable接口的close方法抛出IOException类型的异常,而AutoCloseable接口的close方法抛出Exception类型的异常。

但是为什么呢? AutoCloseable 的关闭方法也可能抛出 IOException 是否有任何示例支持 AutoCloseable 的关闭方法必须抛出 Exception 类型的异常

【问题讨论】:

  • 我认为这对语言制造商来说只是一个糟糕的决定。它要求您在使用 try-with-resources 的任何地方捕获通用异常。

标签: java try-catch try-with-resources


【解决方案1】:

除了IOException 之外,还可以抛出一些其他类型的异常,一个漂亮且常见的用例可以轻松监督:

可以重写接口以完全没有throws 声明,从而允许在没有显式异常处理的情况下编写try

在我们的代码中,我们有一个接口Searcher,以下列方式声明

public interface Searcher<V> extends AutoCloseable {

    Stream<V> search();

    @Override
    void close();
}

这允许以下使用Searcher 实例:

try (Searcher<Datatype> dataTypeSearcher = new DataTypeSearcher(query)) {
    return dataTypeSearcher.search();
}
// without any catch statements

如果AutoCloseable 上没有throws 声明,则上述将是唯一的用法,因为无法覆盖AutoCloseable 接口,抛出未在父级上声明的异常。目前的做法,两种选择都可以。

【讨论】:

    【解决方案2】:

    Closeable 扩展了AutoCloseable,但可能还有其他特定的接口可以扩展此接口。例如:

    public interface MyCloseable extends AutoCloseable { 
        void close() throws RuntimeException; 
    }
    

    他们希望有一个可以在许多情况下使用的接口,这就是他们决定使用Exception 的原因,因为它也适用于其他类型的异常。

    【讨论】:

      【解决方案3】:

      AutoClosable 接口位于java.lang,旨在应用于任何需要“自动”关闭的资源 (try-with-resources)。 AutoClosable 不能是与 io 相关的资源。所以接口不能对具体的异常做任何假设。

      另一方面,Closable 位于java.io 并扩展AutoClosable,因为Closable 是用于io 资源的AutoClosable。因此它声明IOExceptions 可以关闭。

      例如... java.sql.ConnectionAutoClosable,因为它的 close 方法会抛出 SQLExceptionSQLException 不是 IOException。想想内存数据库,关闭 sql 连接不能抛出IOException 是有道理的。

      编辑

      回答了另一个疑问,即为什么 AutoClosable 保存在 java.lang 包下。谢谢。

      我认为它位于java.lang,因为try-with-resources 是作为Java 1.7 中的语言特性引入的。因此java.lang

      【讨论】:

      • 回答了另一个疑问,即为什么 AutoClosable 保留在 java.lang 包下。谢谢。
      • @Vishrant 我更新了我的答案...晚了,但我希望不会太晚:)
      • 事实上,回答了为什么要创建AutoCloseable 而不是仅仅重复使用Closeable
      • 很好的答案,勒内。另一种说法是:请记住 Closeable 在 Java 1.7 之前就存在,它的 close 方法已经在抛出 IOException;我想,当他们引入AutoCloseable 并改造Closeable 以扩展它时,他们发现AutoCloseable.close 必然必须抛出一个检查异常(继承/方法覆盖规则);在这种情况下,Exception 是最明智的选择。
      • The AutoClosable must not be an io releated resource. 这是不正确的,可以通过将“必须”更改为“可能”来纠正。
      猜你喜欢
      • 1970-01-01
      • 2010-10-09
      • 2017-10-22
      • 2018-12-29
      • 1970-01-01
      • 2014-12-15
      • 1970-01-01
      • 1970-01-01
      • 2021-03-04
      相关资源
      最近更新 更多