java autocloseable_Closeable和AutoCloseable的理解

写在前面

我们知道,在java中jvm虚拟机会自动去调用gc(垃圾回收器)去回收堆中没有被引用的对象,至于什么时候回收,是不确定的,同时有些是用到其他资源,jvm也不会进行回收,类似Io流中的FileInputStream使用到了硬盘资源,垃圾回收器是不会去回收的,因此,必须手动关闭掉。我们进行手动的编写close()方法进行关闭,然而,每次这些写会造成代码冗余不优雅,JDK中对于释放资源有Closeable和AutoCloseable可以使用,以下为详解。

一、Closeable

1.1Closeable源码

/**

* 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.

*

*

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

* mark 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操作结束之后都要去释放资源。

(1)如果在调用此方法之前 stream已经关闭 ,则方法失效;

(2)建议先关闭内部的资源,并标记为已关闭;

(3)优先抛出IO异常;

二、AutoCloseable

AutoCloseable接口位于java.lang包下,从JDK1.7开始引入。

由于位于java.lang包下,可以针对于所有实现该接口的流,而closable本身也实现了该接口,java的io流间接性的可以自动关闭接口,也就是说从jdk1.7开始,不需要手动去关流。

2.1AutoCloseable源码

/**

* 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

*

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.

*

*

While this interface method is declared to throw {@code

* Exception}, implementers are strongly 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.

*

*

Cases where the close operation may fail require careful

* attention by implementers. It is strongly advised to relinquish

* the underlying resources and to internally mark 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.

*

*

Implementers of this interface are also strongly advised

* to not have the {@code close} method throw {@link

* InterruptedException}.

*

* 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.

*

*

Note that unlike the {@link java.io.Closeable#close close}

* method of {@link java.io.Closeable}, this {@code close} method

* is not 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中关闭资源存在以下问题:

(1)自己要手动写代码做关闭的逻辑;

(2)有时候还会忘记关闭一些资源;

(3)关闭代码的逻辑比较冗长,不应该是正常的业务逻辑需要关注的;

private static void standard_Method() throws IOException {

FileInputStream fis = null;

FileOutputStream fos = null;

try {

fis = new FileInputStream("xxx.txt");

fos = new FileOutputStream("kkk.txt");

int len = -1;

while((len=fis.read())!=-1) {

fos.write(len);

}

} finally {

try {

if (fis!=null)

fis.close(); //输入输出流能关一个尽量关一个

} finally {

if (fis!=null)

fos.close();

}

}

}

很显然是很繁琐的

jdk1.7之后采用{try}-with-resources的解释

将可能抛出异常的代码块放入到try块中,在try结束的时候,会自动将这些资源关闭(调用close方法)。

2.3{try}-with-resources关键点

带资源的try语句的3个关键点:

(1)由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象。

(2)在try代码中声明的资源被隐式声明为final。

(3)通过使用分号分隔每个声明可以管理多个资源。

private static void autoClosable() throws IOException {

//jdk1.7版本流会自动关闭,实现了AutoClosable接口

try(

FileInputStream fis = new FileInputStream("xxx.txt");

FileOutputStream fos = new FileOutputStream("hhh.txt");

MyAutoClosable closable = new MyAutoClosable();

){

int len = -1;

while((len=fis.read())!=-1) {

fos.write(len);

}

}

}

这样看起来是不是简单,舒服很多

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值