目录
Closeable和AutoCloseable的理解
背景:
在后台开发中,规范编码风格要求,对所有占用的资源进行释放,一般来说,我们进行手动的编写close()方法进行关闭,然鹅,每次这些写会造成代码冗余不优雅,JDK中对于释放资源有Closeable和AutoCloseable可以使用,以下为详解。
一、Closeable
1.1Closeable接口源码:
package java.io;
import java.io.IOException;
/**
* A {@code Closeable} is a source or destination of data that can be closed.
* The close method is invoked to release resources that the object is
* holding (such as open files).
*
* @since 1.5
*/
public interface Closeable extends AutoCloseable {
/**
* Closes this stream and releases any system resources associated
* with it. If the stream is already closed then invoking this
* method has no effect.
*
* <p> As noted in {@link AutoCloseable#close()}, cases where the
* close may fail require careful attention. It is strongly advised
* to relinquish the underlying resources and to internally
* <em>mark</em> the {@code Closeable} as closed, prior to throwing
* the {@code IOException}.
*
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException;
}
1.2使用close需要注意:
在java.io.包下 InputStream,outputStream, Reader, Writer 等基类都实现了Closeable接口,因为每次的IO操作结束之后都要去释放资源。
- 如果在调用此方法之前 stream已经关闭 ,则方法失效;
- 建议先关闭内部的资源,并标记为已关闭;
- 优先抛出IO异常;
二、AutoCloseable
AutoCloseable接口位于java.lang包下,从JDK1.7开始引入。
2.1AutoCloseable源码
package java.lang;
/**
* An object that may hold resources (such as file or socket handles)
* until it is closed. The {@link #close()} method of an {@code AutoCloseable}
* object is called automatically when exiting a {@code
* try}-with-resources block for which the object has been declared in
* the resource specification header. This construction ensures prompt
* release, avoiding resource exhaustion exceptions and errors that
* may otherwise occur.
*
* @apiNote
* <p>It is possible, and in fact common, for a base class to
* implement AutoCloseable even though not all of its subclasses or
* instances will hold releasable resources. For code that must operate
* in complete generality, or when it is known that the {@code AutoCloseable}
* instance requires resource release, it is recommended to use {@code
* try}-with-resources constructions. However, when using facilities such as
* {@link java.util.stream.Stream} that support both I/O-based and
* non-I/O-based forms, {@code try}-with-resources blocks are in
* general unnecessary when using non-I/O-based forms.
*
* @author Josh Bloch
* @since 1.7
*/
public interface AutoCloseable {
/**
* Closes this resource, relinquishing any underlying resources.
* This method is invoked automatically on objects managed by the
* {@code try}-with-resources statement.
*
* <p>While this interface method is declared to throw {@code
* Exception}, implementers are <em>strongly</em> encouraged to
* declare concrete implementations of the {@code close} method to
* throw more specific exceptions, or to throw no exception at all
* if the close operation cannot fail.
*
* <p> Cases where the close operation may fail require careful
* attention by implementers. It is strongly advised to relinquish
* the underlying resources and to internally <em>mark</em> the
* resource as closed, prior to throwing the exception. The {@code
* close} method is unlikely to be invoked more than once and so
* this ensures that the resources are released in a timely manner.
* Furthermore it reduces problems that could arise when the resource
* wraps, or is wrapped, by another resource.
*
* <p><em>Implementers of this interface are also strongly advised
* to not have the {@code close} method throw {@link
* InterruptedException}.</em>
*
* This exception interacts with a thread's interrupted status,
* and runtime misbehavior is likely to occur if an {@code
* InterruptedException} is {@linkplain Throwable#addSuppressed
* suppressed}.
*
* More generally, if it would cause problems for an
* exception to be suppressed, the {@code AutoCloseable.close}
* method should not throw it.
*
* <p>Note that unlike the {@link java.io.Closeable#close close}
* method of {@link java.io.Closeable}, this {@code close} method
* is <em>not</em> required to be idempotent. In other words,
* calling this {@code close} method more than once may have some
* visible side effect, unlike {@code Closeable.close} which is
* required to have no effect if called more than once.
*
* However, implementers of this interface are strongly encouraged
* to make their {@code close} methods idempotent.
*
* @throws Exception if this resource cannot be closed
*/
void close() throws Exception;
}
2.2.{try}-with-resources的使用注意
在1.7之前,我们通过try{} finally{} 在finally中释放资源。
在finally中关闭资源存在以下问题:
- 自己要手动写代码做关闭的逻辑;
- 有时候还会忘记关闭一些资源;
- 关闭代码的逻辑比较冗长,不应该是正常的业务逻辑需要关注的;
2.3.{try}-with-resources的解释
对于实现AutoCloseable接口的类的实例,将其放到try后面(我们称之为:带资源的try语句,源码中的({@code{try}-with-resources)),在try结束的时候,会自动将这些资源关闭(调用close方法)。
官网解释:
An object that may hold resources (such as file or socket handles) until it is closed. The close() method of an AutoCloseable object is called automatically when exiting a try-with-resources block for which the object has been declared in the resource specification header. This construction ensures prompt release, avoiding resource exhaustion exceptions and errors that may otherwise occur.
(一个可以保存资源(如文件或套接字句柄)直到它被关闭的对象。AutoCloseable对象的close()方法在退出资源块时被自动调用,资源块是在资源规范头中声明的对象。这种构造确保了快速释放,避免了可能发生的资源耗尽异常和错误。 )
2.4{try}-with-resources关键点
带资源的try语句的3个关键点:
- 由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象。
- 在try代码中声明的资源被隐式声明为fianl。
- 通过使用分号分隔每个声明可以管理多个资源。
简单来说,实现了AutoCloseable接口的类再在执行结束后自动执行close方法来释放资源。比如:
public class AutoCloseableTest {
public static void main(String [] args){
try(ConnectionLock lock = new ConnectionInnerLock()){
//do something lock
System.out.println("doing business...");
} catch (Exception e) {
e.printStackTrace();
}
}
}
interface ConnectionLock extends AutoCloseable{
/**
* 释放资源
*/
void unlock();
}
class ConnectionInnerLock implements ConnectionLock{
/**
* 释放资源
*/
@Override
public void unlock(){
//do release resource
System.out.println("release resource ");
}
@Override
public void close() throws Exception {
this.unlock();
}
}
参考:
https://docs.oracle.com/javase/8/docs/api/index.html
https://docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html
https://www.jianshu.com/p/958ea3a269b4