Try-With-Resource 的用法

在 Java7 之前,如果我们的程序打开了一个IO 流,那么在发生异常或者运行结束时需要调用 close() 关闭 IO 流。那么需要像这样编写代码

public class MessyExceptions {
public static void main(String[] args) {
InputStream in = null;
try {
in = new FileInputStream(
new File("MessyExceptions.java"));
int contents = in.read();
// Process contents
} catch(IOException e) {
// Handle the error
} finally {
if(in != null) {
try {
in.close();
} catch(IOException e) {
// Handle the close() error
}
}
}
}
}

代码中 finally 语句块中还包含着 try 语句,使得代码看起来过于复杂。

而在 Java7 引入 try-with-resources 语法,可以简化上述代码

public class TryWithResources {
public static void main(String[] args) {
try(
InputStream in = new FileInputStream(
new File("TryWithResources.java"))
) {
int contents = in.read();
// Process contents
} catch(IOException e) {
// Handle the error
}
}
}
try-with-resources 语法
try(){
}catch(){
}

在 try-with-resources 定义子句中创建的对象(在括号内的对象)必须实现 java.lang.AutoCloseable 接口,这个接口有一个方法:close()。

当 try() 括号里面的 IO 出现异常或者运行结束,会自动调用 close() 关闭对象。

try-with-resources 中的 try 语句也可以不加 catch 和 finall 而独立存在。

try-with-resources 基本运行机制

创建自定义实现 AutoCloseable 接口的类

class Reporter implements AutoCloseable {
String name = getClass().getSimpleName();
Reporter() {
System.out.println("Creating " + name);
}
public void close() {
System.out.println("Closing " + name);
}
}
class First extends Reporter {}
class Second extends Reporter {}
public class AutoCloseableDetails {
public static void main(String[] args) {
try(
First f = new First();
Second s = new Second()
) {
}
}
}
输出
Creating First
Creating Second
Closing Second
Closing First

退出 try 块会调用两个对象的 close() 方法,并以与创建顺序相反的顺序关闭它们。顺序很重要,因为在此配置中,Second 对象可能依赖于 First 对象,因此如果 First 在第 Second 关闭时已经关闭。 Second 的 close() 方法可能会尝试访问 First 中不再可用的某些功能。