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

时间:2014-09-21 13:36:42

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

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

  

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

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

3 个答案:

答案 0 :(得分:12)

AutoClosable界面位于java.lang,旨在应用于需要“自动”关闭的任何资源(try-with-resources)。 AutoClosable不能是io相关资源。所以界面不能做出任何具体例外的假设。

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

例如...... java.sql.ConnectionAutoClosable,因为它的关闭方法会引发SQLExceptionSQLException不是IOException。在内存DB中考虑一下,关闭sql连接不能抛出IOException

修改

  

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

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

答案 1 :(得分:6)

Closeable扩展AutoCloseable,但可能有其他特定接口扩展此接口。 E.g:

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

他们希望有一个可以在很多情况下使用的界面,这就是他们决定使用Exception的原因,因为它也适用于其他类型的例外。

答案 2 :(得分:3)

除了能够抛出一些其他类型的异常而不是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

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