关闭资源.close()语句放在try里面好还是finally里面好?

时间:2022-04-22 18:20:49

以下有3种方法关闭PrintWriter,第一种将.close()放在try里面,第二种放在finally里面,第三种使用了JAVA 7的新特性try-with-resources语句,哪种最好呢?

//close() is in try clause
try {
PrintWriter out = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)));
out.println("the text");
out.close();
} catch (IOException e) {
e.printStackTrace();
}

//close() is in finally clause
PrintWriter out = null;
try {
out = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)));
out.println("the text");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (out != null) {
out.close();
}
}

//Java 7, try-with-resource statement
try (PrintWriter out2 = new PrintWriter(
new BufferedWriter(
new FileWriter("out.txt", true)))) {
out2.println("the text");
} catch (IOException e) {
e.printStackTrace();
}

回答其实很简单,因为不管有没有发生异常,我们都需要关闭PrintWriter,所以.close()最好放到finally里面!

当然,从JAVA 7开始,我们也可以使用try-with-resource。

try-with-resources 语句是一个声明了1到多个资源的try语句。资源是指这个try执行完成后必需close掉的对象,比如connection, resultset等。
try-with-resources 语句会确保在try语句结束时关闭所有资源。实现了java.lang.AutoCloseable或java.io.Closeable的对象都可以做为资源。
下面是一个例子,它会从一个文件中读出首行文本,这里使用了BufferedReader 的实例来读取数据,BufferedReader 是一个资源,它应该在程序完成时被关闭。

static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}

在这个例子里面,资源是一个BufferedReader, 声明语句是在try后面的括号内。在java7或更晚的版本中,BufferedReader实现了java.lang.AutoCloseable接口。由于BufferedReader被定义在try-with-resource 语句中,因此不管try代码块是正常完成或是出现异常,这个BufferedReader 的实例都将被关闭。

注意:try-with-resources 也可以有catch和finally语句块,就像使用一个普通的try语句一样。在try-with-resources 语句中,catch或者finally将在资源被关闭后执行。