首先,对于java小白来说,并不清除try-finally或try-with-resources会用在什么地方,云里雾里的。简单来说,文件上传、下载里会频繁用到。
以前的写法:
public class File {
//try-finally-----不再是关闭资源的最佳方式
public static String firstLineOfFile(String path) throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
}
}
这看起来不算差,但,加入第二个资源时,就糟糕了:
static void copy(String src, String dst) throws IOException {
FileInputStream in = new FileInputStream(src);
try {
FileOutputStream out = new FileOutputStream(dst);
try {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read()) >= 0) {
out.write(buf, 0, n);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
是不是看起来特别乱?乱还不是最主要的,最主要的是最内部的try代码块中如果有运行报错信息抛异常,外部try代码块是看不到的,直接覆盖了,这才是致命伤。
用try-with-resources修改后第一部分代码:
// BufferedReader br = new BufferedReader(new FileReader(path));
// try {
// return br.readLine();
// } finally {
// br.close();
// }
// try-with-resources-----最佳资源关闭方式
try(BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
}
用try-with-resources修改后第二部分代码:
// FileInputStream in = new FileInputStream(src);
//
// try {
// FileOutputStream out = new FileOutputStream(dst);
//
// try {
// byte[] buf = new byte[BUFFER_SIZE];
// int n;
// while ((n = in.read()) >= 0) {
// out.write(buf, 0, n);
// }
// } finally {
// out.close();
// }
//
// } finally {
// in.close();
// }
// }
try (FileInputStream in = new FileInputStream(src);
FileOutputStream out = new FileOutputStream(dst)) {
byte[] buf = new byte[BUFFER_SIZE];
int n;
while ((n = in.read()) >= 0) {
out.write(buf, 0, n);
}
}
}
与使用try-finally原始版本相比,使用try-with-resources更短,可读性更强,还不用手写资源关闭,也不用考虑内部异常抛出这些问题。
可以使用try-with-resources语句中放入catch子句。
static String firstLineOfFile(String path, String defaultVal) {
// try-with-resources-----带有catch子句
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
return br.readLine();
} catch (Exception e) {
return defaultVal;
}
}
结论非常明显了:在处理必须关闭资源时,应该总是选择try-with-resources,这样得到的代码更短、更清晰,生成的异常也更有价值。