您的位置:首页 > 编程语言 > Java开发

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

2018-01-22 23:12 405 查看

接口

接口
AutoCloseable
概述

源码解析

总结

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

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();

4000
} 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("关闭资源");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: