引言:
Java 7 引入了try-with-resources 语句,本文将详细介绍 try-with-resources 的工作原理,优点以及如何在日常编程中有效使用它。
1. try-with-resources 简介:
try-with-resources 是一种特殊的 try 语句,它确保在语句执行完毕后,每个资源会被自动关闭。这一特性主要用于那些实现了 java.lang.AutoCloseable
或 java.io.Closeable
接口的资源对象,这包括所有的I/O类如 InputStream
、OutputStream
、java.sql.Connection
等。
2. 传统 try-catch-finally 对比 try-with-resources
以下是一个未使用 try-with-resources 但使用传统 try-catch-finally 语句来确保资源关闭的例子:
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("file.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在上面的代码中,资源 BufferedReader
是在 try 块外面声明的,并在 finally 块中显式关闭。这样做确保了无论 try 块中的代码是否抛出异常,资源都将被关闭。然而,这种方式有几个缺点:
- 代码冗余:finally 块需要显式地检查资源是否为 null,如果不为 null,则需要再次捕获和处理关闭资源时可能抛出的异常。
- 错误处理复杂:如果 try 块和 finally 块中的代码都抛出异常,那么来自 try 块的异常可能会被 finally 块中的异常覆盖,导致原始异常信息丢失。
- 可读性较差:增加的异常处理和资源管理代码使得主逻辑不那么清晰,可读性和可维护性都有所降低。
3. 如何使用 try-with-resources:
使用 try-with-resources 语句非常简单。你只需要声明一个或多个资源在try语句内,这些资源会在try代码块执行完后自动被关闭。这里是一个典型的例子:
try (BufferedReader br = new BufferedReader(new FileReader("file.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
在上述代码中,BufferedReader
是在 try 语句中声明的。无论 try 块内的代码如何执行,无论是正常完成还是遇到异常,BufferedReader
都会在结束后自动关闭。
4. 优点:
使用 try-with-resources 语句的主要优点包括:
- 减少代码冗余:自动关闭资源的特性消除了手动关闭资源的需要,减少了代码量。
- 提高资源管理效率:自动管理资源减少了因为异常或错误忘记关闭资源的风险。
- 提升代码可读性:通过减少错误处理和清理代码,使主逻辑更清晰,易于维护。
5. 注意事项:
尽管 try-with-resources 是一个非常有用的工具,但在使用时还是需要注意几个方面:
- 只有实现了
AutoCloseable
或Closeable
接口的资源才能被用在这种类型的try语句中。 - 如果try块中打开了多个资源,它们会按照声明的相反顺序关闭。
- 自定义资源类时,确保正确实现
close()
方法。