读jdk源码的第一天——java.lang.AutoCloseable

接口

AutoCloseable

1. 概述

可能保存资源的对象(例如文件),直到关闭。AutoCloseable对象的close()方法在退出try- with-resources块时被自动调用,该块在资源规范头中声明了该对象。此构造确保及时释放,避免资源耗尽异常和可能出现的错误。
即使不是所有的子类或实例都拥有可释放的资源,基本类也可以实现自动关闭。对于必须具有完全通用性的代码,或者当已知AutoCloseable实例需要资源释放时,建议使用try- with-resources结构。然而,在用非IO流时没有必要用try-with-resources。

2. 源码解析

 public interface AutoCloseable {
   /**
     * 关闭该资源,放弃任何潜在资源。
     *此方法将自动在try-with-resources语句管理的对象上调用。
     *
     * 虽然该接口方法被声明为抛出异常,但强烈鼓励实现者声明close()方法的具体实现,
     * 以抛出更多特定的异常,或者如果关闭操作不能失败,也不抛出异常。
     *
     * 关闭操作可能失败的情况需要实现者仔细注意。在抛出异常之前,强烈建议放弃
     * 底层资源并在内部标记资源。close方法不太可能被多次调用,因此这确保了资源
     * 的及时发布。此外,它还减少了资源包装或被其他资源包装时可能出现的问题。
     *
     *
     * @throws Exception 如果资源不能关闭
     */
     void close() throws Exception;

 }

3. 总结

已知子接口,和实现类太多了就没有写在上面,在这挑几个常见的来说说,
子接口:Closeable, Connection
Closeable是在java.io包里的也就一个方法。

public interface Closeable extends AutoCloseable{
    public void close() throws IOException;
}

用处也是关闭这个流并释放与之关联的任何系统资源。如果流已经关闭然后调用这个方法没有效果。
Connection是在java.sql包下

public interface Connection  extends Wrapper, AutoCloseable {
    void close() throws SQLException
}

用处是立即释放此 Connection 对象的数据库和 JDBC 资源,而不是等待它们被自动释放。

这些方法都遵循了 实现者声明 close()方法的具体实现,以抛出更多特定的异常,或者如果关闭操作不会失败,也不抛出异常。
实现类
BufferedInputStream
此类也是java.io包下的

public class BufferedInputStream extends FilterInputStream {
    protected volatile byte buf[];
    private static final
        AtomicReferenceFieldUpdater<BufferedInputStream, byte[]> bufUpdater =
        AtomicReferenceFieldUpdater.newUpdater
        (BufferedInputStream.class,  byte[].class, "buf");
   // 带参数构造函数
    public BufferedInputStream(InputStream in, int size) {
        super(in);
        if (size <= 0) {
            throw new IllegalArgumentException("Buffer size <= 0");
        }
        buf = new byte[size];
    }
    public void close() throws IOException {
        byte[] buffer;
        while ( (buffer = buf) != null) {
            if (bufUpdater.compareAndSet(this, buffer, null)) {
                InputStream input = in;
                in = null;
                if (input != null)
                    input.close();
                return;
            }
            // 如果在fill()中装入新的buf,则需要重试
        }
    }

close执行步骤
定义一个byte数组 buffer,把buf 数组赋值给buffer。如果buffer不为null,就把buffer更新为null
更新成功 ,定义一个InputStream对象,并把 in赋值给input,然后让in指向null。如果input不为空 就执行 input.close(),最后跳出。

4. 对try-with-resources和传统释放资源对比

public class AutoCloseableTest {
    /**
     * 演示传统的资源释放方式
     */
    @Test
    public void traditionTest(){
        SubAutoCloseable subAutoCloseable = null;
        try {
            subAutoCloseable = new SubAutoCloseable();
            subAutoCloseable.readResouse();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if(subAutoCloseable != null){
                try {
                    subAutoCloseable.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * JDK1.7 新特性 try-with-resources
     */
    @Test
    public void test(){
        try(SubAutoCloseable subAutoCloseable = new SubAutoCloseable()){
            subAutoCloseable.readResouse();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

public class SubAutoCloseable implements AutoCloseable{

    public void readResouse(){
        System.out.println("正在读取资源");
    }
    @Override
    public void close() throws Exception {
        System.out.println("关闭资源");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值