1. AutoCloseable接口
在1.7之前,我们通过try{} finally{} 在finally中释放资源。
在finally中关闭资源存在以下问题:
1. 自己要手动写代码做关闭的逻辑;
2. 有时候还会忘记关闭一些资源;
3. 关闭代码的逻辑比较冗长,不应该是正常的业务逻辑需要关注的;
对于实现AutoCloseable接口的类的实例,将其放到try后面(我们称之为:带资源的try语句),在try结束的时候,会自动将这些资源关闭(调用close方法)。
带资源的try语句的3个关键点:
1. 由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象。
2. 在try代码中声明的资源被隐式声明为fianl。
3. 通过使用分号分隔每个声明可以管理多个资源。
/**
* 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.
* (自动关闭资源)资源不需要时,必须关闭
* @author Josh Bloch
* @since 1.7
*/
public interface AutoCloseable {
/**
* 关闭资源,舍弃任何潜在的资源。通过try-with-resources语句在使用对象上自动调用该方法.
*
* 当这个接口方法被声明时,被抛出异常,强调具体的close()方法时,抛出更具体的异常,
* 若果关闭操作成功,则没有任何异常抛出。
*
* 强烈建议该方法的实现时抛出InterruptedException,该异常与线程中断状态进行交互,
* 同时该异常被抑制,则可能出现运行时错误。
*
* 一般说来,若果出现一个异常被压制,AutoCloseable.close并不能抛出该异常。
*
* 请注意:这个方法与java.io.Closeable中close()方法并不相同,该方法不要求是幂等的。
* 换句话说,多次调用该方法可能出现不同的效果,而Closeable.close()方法,多次调用和 一次调用效果是一致的。
*
* 然而,强烈要求实现者使用该方法接近幂等。
*
*/
void close() throws Exception;
2. Closeable接口
Closeable接口也定义了close()方法。实现了Closeable接口的类的对象可以被关闭。
从JDK7开始,Closeable扩展了AutoCloseable。
因此,在JDK7中,所有实现了Closeable接口的类也都实现了AutoCloseable接口。
/**
* 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.
*
* 关闭流及释放与其相关的任何系统资源
* 如果一个流已经关闭,则调用该方法无效。
* @throws IOException if an I/O error occurs
*/
public void close() throws IOException;
}
3. 三七互娱笔试
public class MyResource1 implements AutoCloseable {
@Override
public void close() throws IOException {
System.out.println(1);
}
}
public class MyResource2 implements Closeable {
@Override
public void close() throws IOException {
throw new IOException();
}
}
public class TestRes {
public static void main(String[] args) {
try(MyResource1 r1 = new MyResource1(); //带资源的try语句
MyResource2 r2 = new MyResource2();){
System.out.println("T");
}catch (IOException e){
System.out.println("IOE");
}finally {
System.out.println("F");
}
}
}
问:输出什么???
分析:
1. 上面的例子在try关键字后的括号里创建了两个资源
2. 当程序运行离开try语句块时,这两个资源都会被自动关闭。
3. 这些资源将按照他们被创建顺序的逆序来关闭。(抛出的异常最后执行)
T
1
IOE
F