简介
Java 7 增加了一个新特性,该特性提供了一种管理资源的方式,这种方式能自动关闭文件。这个特性有时被称为自动资源管理(Automatic Resource Management, ARM)。
该特性以 try 语句的扩展版为基础。自动资源管理主要用于,当不再需要文件(或其他资源)时,可以防止无意中忘记释放它们。
当 try 代码块结束时,自动释放资源。因此不需要显示的调用 close() 方法。该形式也称为“带资源的 try 语句”。
简而言之,就是当我们使用一些需要关闭的资源(例如IO流对象等)
时,不在需要在try…catch…finally语法模板的finally代码块中去释放他。
用法模板
try(需要关闭的资源声明){
//可能发生异常的语句
}catch(异常类型 变量名){
//异常的处理语句
}
……
finally{
//一定执行的语句
}
需要注意的点
- ①try 语句中声明的资源被隐式声明为 final ,资源的作用局限于带资源的 try 语句
- ②可以在一条 try 语句中管理多个资源,每个资源以“;”(分号) 隔开即可。
- ③需要关闭的资源,必须实现了 AutoCloseable 接口或其自接口 Closeable
AutoCloseable 接口及其子类
大致的意思说
- 即使不是所有的子类或实例都拥有可释放的资源,基类也有可能实现AutoCloseable
- 在已知实例需要资源释放,建议使用该模式
- 支持基于I/O和非基于I/O的表单,不建议使用该模式
再看其子类:
一些常用的IO流对象都间接实现了这个方法
使用代码
我们通过一段代码来比较自动释放
和手动释放
的区别。
传统方法
首先是传统的手动释放资源的办法
public class TryTest {
public static void main(String[] args) {
FileInputStream inputStream = null;
FileOutputStream outputStream = null;
try{
// 资源操作代码
inputStream = new FileInputStream("Java.pdf");
outputStream = new FileOutputStream("JavaTe.pdf");
byte[] bytes = new byte[1024];
while(inputStream.read(bytes) != -1){
outputStream.write(bytes);
}
}catch (Exception e){
e.printStackTrace();
}finally {
// 资源不为空就关闭
try {
if(inputStream != null){
inputStream.close();
}
if(outputStream != null){
outputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
JDK7方法
下面是自动释放资源
public class TryTest {
public static void main(String[] args) {
try(
// 在try()的括号中声明并创建自动关闭对象
FileInputStream inputStream = new FileInputStream("Java.pdf");
FileOutputStream outputStream = new FileOutputStream("JavaTry.pdf");
){
// 资源操作代码
byte[] bytes = new byte[1024];
while(inputStream.read(bytes) != -1){
outputStream.write(bytes);
}
}catch (Exception e){
e.printStackTrace();
}
}
}
编译文件
JDK7以后为什么能支持资源自动关闭呢,我们可以通过.class字节码文件
来看出猫腻
源文件:
字节码文件:
- 我们首先看到,在
try()
中声明并初始化的IO流在字节码文件
中体现出在try{}
代码块中 - 并且自动添加了
finally{}
语句进行一些IO流关闭操作 - 关闭操作也是按照我们编写的,最先打开的最后关闭进行编写。
注意事项
需要注意,要自动关闭的对象。声明和创建
都直接放在try()
语句块中,如果单独拉出来声明会报错。
错误图例:
对比手动释放:
手动释放只需要将会报错的代码
放在try{}
语句块中即可。