为什么java.lang.AutoCloseable的close方法抛出异常,而java.io.Closeable的close方法抛出IOException?

为什么java.lang.AutoCloseable的close方法抛出异常,而java.io.Closeable的close方法抛出IOException?,java,try-catch,try-with-resources,Java,Try Catch,Try With Resources,我读这篇文章是为了try with resources,上面写着: Closeable接口的close方法抛出类型为IOException的异常,而AutoCloseable接口的close方法抛出类型为Exception的异常 但是为什么呢?AutoCloseable的close方法也可能抛出IOException是否有任何示例支持AutoCloseable的close方法必须抛出类型为Exception的异常AutoCloseable接口位于java.lang中,并打算应用于任何需要“自动”

我读这篇文章是为了
try with resources
,上面写着:

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


但是为什么呢?
AutoCloseable
的close方法也可能抛出
IOException
是否有任何示例支持
AutoCloseable
的close方法必须抛出类型为
Exception
的异常
AutoCloseable
接口位于
java.lang
中,并打算应用于任何需要“自动”关闭的资源()。
AutoClosable
不能是io相关资源。因此,接口不能做出任何具体异常的假设

另一方面,
Closable
位于
java.io
中并扩展了
AutoClosable
,因为
Closable
是io资源的
AutoClosable
。因此,它声明可以在关闭时抛出
IOException
s

例如。。。
java.sql.Connection
是一个
AutoClosable
,因为它的close方法抛出
SQLException
,而
SQLException
不是
IOException
。考虑内存中的DBs,关闭sql连接不能引发
IOException
,这是有道理的

编辑


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


我认为它位于
java.lang
中,因为它是在Java1.7中作为一种语言特性引入的。因此,
java.lang
Closeable
扩展了
AutoCloseable
,但可能还有其他特定的接口扩展了此接口。例如:

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

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

除了能够抛出
IOException
之外的一些其他类型的异常,一个漂亮而常见的用例可以很容易地监督:

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

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

public interface Searcher<V> extends AutoCloseable {

    Stream<V> search();

    @Override
    void close();
}

如果
AutoCloseable
上不存在任何
throws
声明,则上述将是唯一的用法,因为无法覆盖
AutoCloseable
接口,该接口将引发未在父级上声明的异常。按照目前的方式,这两个选项都是可能的。

回答了另一个疑问,即为什么
AutoClosable
保存在
java.lang
包下。谢谢。@Vishrant我更新了我的答案。。。很晚,但我希望不会太晚:)事实上,我回答了为什么创建了
AutoCloseable
,而不是仅仅重用
Closeable
。回答得很好,勒内。另一种说法是:请记住,
Closeable
在Java1.7之前就存在,并且它的
close
方法已经抛出了
IOException
;我想,当他们引入
AutoCloseable
并改进
Closeable
以扩展它时,他们发现
AutoCloseable.close
必须抛出一个选中的异常(继承/方法重写规则)<代码>例外是这种情况下最明智的选择。
自动关闭不能是io相关资源。
这是不正确的,可以通过将“必须”改为“可以”来纠正。我认为这只是语言制作者的错误决定。它要求您在使用try-with-resources的任何地方捕获一般异常。
try (Searcher<Datatype> dataTypeSearcher = new DataTypeSearcher(query)) {
    return dataTypeSearcher.search();
}
// without any catch statements