概述
本文介绍 try-with-resources 的使用以及带来的好处
try-with-resources 概念
在实际项目开发为了避免资源泄漏,最好的做法是在 finally 块中关闭资源对象(如 File OutputStream等)。
原因是 finally 块即使在出现异常时也会被执行
但是不要在 try 语句中关闭资源,因为当 try 块中的语句抛出异常或者自己实现的代码抛出异常,那么就不会执行最后的关闭语句,从而资源也无法释放。
与在 finally 块中关闭资源不同,try-with-resources 只是一个语法糖,用于关闭任何资源类(实现了 Auto close able )对象(在Java1.7中引入),
try-with-resources 相比 try–catch-finally 来说不需要手动去关闭资源,只要根据约定实现了 AutoCloseable 接口,就会自动调用 close 方法。
关键点
- try 圆括号中的资源必须实现 AutoCloseable 接口
- try-with-resources 是在 Java1.7 中引入的
- 不要在 try 语句中做关闭资源的操作
举例说明
try–catch-finally 实现
Scanner scanner = null;
try {
scanner = new Scanner(new File(" Test .txt"));
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFound Exception e) {
e.printStackTrace();
} finally {
if (scanner != null) {
scanner.close();
}
}
try-with-resources 实现
try (Scanner scanner = new Scanner(new File("test.txt"))) {
while (scanner.hasNext()) {
System.out.println(scanner.nextLine());
}
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
也可以支持多行,具体如下
try (Scanner scanner = new Scanner(new File("testRead.txt"));
PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
while (scanner.hasNext()) {
writer.print(scanner.nextLine());
}
}
try-with-resources 解决的问题
- try-with-resources 明确了需要关闭资源的对象,这些对象必须实现 AutoCloseable 对象
- 相对于 try-catch-finally 来说简化了代码,try-with-resources 不需要在 finally 代码库中调用 close 方法
try-with-resources 中的资源关闭顺序
这里通过一个例子来测试一下
- 实现了 AutoCloseable 接口的 MyAutoClose1 和 MyAutoClose2 如下
public class MyAutoClose1 implements AutoCloseable {
private static final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public void work() {
logger.info("work");
}
@Override
public void close() throws Exception {
logger.info("close");
}
}
public class MyAutoClose2 implements AutoCloseable {
private static final Logger logger =
LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
public void work() {
logger.info("work");
}
@Override
public void close() throws Exception {
logger.info("close");
}
}
- 测试代码如下
@Test
public void test1() {
try (
final MyAutoClose1 myAutoClose1 = new MyAutoClose1();
final MyAutoClose2 myAutoClose2 = new MyAutoClose2();
) {
myAutoClose1.work();
myAutoClose2.work();
} catch (final Exception e) {
e.printStackTrace();
}
}
- 执行如下
19:51:06.755 [main] INFO c.c.xutils.test.trys.MyAutoClose1 - work
19:51:06.758 [main] INFO c.c.xutils.test.trys.MyAutoClose2 - work
19:51:06.758 [main] INFO c.c.xutils.test.trys.MyAutoClose2 - close
19:51:06.758 [main] INFO c.c.xutils.test.trys.MyAutoClose1 - close