finally块用于确保资源释放,无论异常是否发生都会执行,常用于关闭文件流等操作,需注意避免return和二次异常,推荐优先使用try-with-resources。

在Java中,finally块是异常处理机制的重要组成部分,常用于确保关键资源(如文件流、网络连接、数据库连接等)无论是否发生异常都能被正确释放。合理使用finally块,可以有效避免资源泄漏,提升程序的健壮性。
finally块的基本作用
finally块紧跟在try-catch语句之后,其代码无论是否抛出异常都会执行。这一特性使其成为释放资源的理想位置。
典型结构如下:
try {
// 可能出现异常的操作
} catch (ExceptionType e) {
// 异常处理
} finally {
// 一定会执行的清理代码
}
即使try块中发生异常并被catch捕获,或未被捕获导致方法退出,finally中的代码仍会运行(除极端情况如JVM崩溃或调用System.exit())。
立即学习“Java免费学习笔记(深入)”;
使用finally释放常见资源
在操作I/O流、数据库连接等需要手动管理资源的场景中,finally块尤为关键。
示例:关闭文件流
FileInputStream fis = null;
try {
fis = new FileInputStream("data.txt");
int data = fis.read();
while (data != -1) {
System.out.print((char) data);
data = fis.read();
}
} catch (IOException e) {
System.err.println("读取文件出错:" + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
System.err.println("关闭流时出错:" + e.getMessage());
}
}
}
注意:关闭资源本身也可能抛出异常,因此close()调用应放在try-catch中,避免掩盖原始异常。
对比try-with-resources语句
从Java 7开始,引入了try-with-resources语句,它自动管理实现了AutoCloseable接口的资源,语法更简洁,推荐优先使用。
上述例子可简化为:
try (FileInputStream fis = new FileInputStream("data.txt")) {
int data = fis.read();
while (data != -1) {
System.out.print((char) data);
data = fis.read();
}
} catch (IOException e) {
System.err.println("读取文件出错:" + e.getMessage());
}
// 流会自动关闭,无需finally块
但在某些旧版本Java项目或非AutoCloseable资源(如线程池、自定义资源锁)中,仍需依赖finally块进行清理。
finally块使用注意事项
使用finally时需注意以下几点以避免陷阱:
- 不要在finally块中使用return语句,否则可能覆盖try或catch中的返回值或异常。
- 避免在finally中抛出异常或执行耗时操作,影响程序正常流程。
- 确保资源判空后再调用关闭方法,防止NullPointerException。
- 若try块中有return语句,finally会先执行再返回,可用于收尾逻辑。
基本上就这些。finally块是保障资源安全释放的可靠手段,尤其在无法使用try-with-resources的场景下不可或缺。结合实际需求选择合适的方式,才能写出更稳定、易维护的Java代码。










