AutoCloseable接口
我们都知道,Java中进行资源操作后,比如文件操作、数据库操作等,必须手动关闭资源链接。这样看来,手动关闭的代码好像变成了模板代码,Java有没有提供一种可以自动实现关闭资源的方法呢?有的,就是从JDK 7开始提供的AutoCloseable接口。
public interface AutoCloseable { void close() throws Exception;}
这是AutoCloseable接口,其只有一个close()方法,并且抛出有Exception异常。这里抛出Exception异常是因为该接口可能会应用于不同的场景,如文件关闭、线程关闭、数据库连接关闭等,所以抛出一个通用的Exception异常。
这个接口有什么用呢?我们看一下它上面的声明(翻译成了中文,可能翻译的不好将就看):
这是一个直到关闭前都持有资源的接口。当一个类实现了AutoCloseable接口,当这个类的实例持有资源并退出try-with-resources块时,将自动调用AutoCloseable接口的close()方法。这种构造可确保及时释放,避免资源耗尽异常和可能发生的错误。(try-with-resources结构看下面的示例代码就知道了)
即使不是所有子类或实例都拥有可释放的资源,基类也有可能(实际上是常见的)实现AutoCloseable。对于必须完全通用的代码,或已知实例需要AutoCloseable接口释放资源的代码,建议使用try-with-resources结构。但是,当使用同时支持基于I / O和基于非I / O的形式的java.util.stream.Stream}之类的工具时除外。
其外,声明中还强烈建议:
- 虽然此接口声明为抛出Exception异常,但实现者应该实现抛出更具体地异常,或者不抛出异常。
- 强烈建议引发异常前,先放弃基础资源,并在内部对这些资源标记为已关闭
- 强烈建议该接口实现者不要抛出InterruptedException异常,因为会导致抑制异常问题
- close()方法不强制要求幂等,但建议该接口实现者将其实现为幂等。
下面用一个例子来看一看AutoCloseable该如何用。
一个例子
一般来讲,如果我们使用资源,代码会这么写:
如果用AutoCloseable的话,代码可以这样写:
注意代码中的第三行-“try(FILE file = new FILE())”,如果将try中创建FILE对象的语句放到try外面,则不会自动执行close方法,这就是try-with-resources结构。
这里自动执行了close()方法。不需要我们在业务代码中手动关闭,减少了模板代码。