使用try - catch - finally优化示例
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("test.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();
}
}
}
}
}
使用try - with - resources优化示例
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class FileReadExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
两种方式在异常处理和资源管理上的区别
- 异常处理:
- try - catch - finally:在
finally
块中关闭资源时,如果关闭操作也抛出异常,会掩盖之前在try
块中抛出的异常,导致调试困难。例如,try
块中读取文件出错抛出异常,finally
块关闭流也出错抛出异常,最终只有finally
块的异常会被捕获。
- try - with - resources:在
try - with - resources
语句中,当try
块和资源关闭操作都抛出异常时,try
块中的异常会被保留,资源关闭抛出的异常会被抑制(suppressed),可以通过getSuppressed()
方法获取。这使得主要异常信息不会被掩盖,方便调试。
- 资源管理:
- try - catch - finally:需要手动在
finally
块中关闭资源,并且要进行非空检查,代码相对冗长,容易遗漏关闭操作。
- try - with - resources:只要实现了
AutoCloseable
接口的资源,在try
块结束时(正常结束或异常结束)都会自动关闭,无需手动在finally
块中编写关闭代码,代码更简洁,减少了因忘记关闭资源而导致资源泄漏的风险。
优先选择场景
- 优先选择try - with - resources的场景:
- 当处理实现了
AutoCloseable
接口的资源时,优先使用try - with - resources
,如文件流、数据库连接等。因为它代码简洁,能有效避免资源泄漏,并且在异常处理上更合理,能保留主要异常信息。
- 优先选择try - catch - finally的场景:
- 当处理的资源没有实现
AutoCloseable
接口,或者需要在关闭资源时执行一些特殊逻辑(如记录日志等),则需要使用try - catch - finally
方式。但这种场景相对较少,大多数资源都实现了AutoCloseable
接口。