为什么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