finally块总在try执行后运行,确保资源释放;需null检查和嵌套try-catch防关闭异常;return值在finally前已暂存;优先用try-with-resources自动管理AutoCloseable资源。

在 Java 中,finally 块是确保资源(如文件流、数据库连接、网络套接字等)被释放的可靠机制之一——只要 try 块开始执行,无论是否发生异常、是否提前 return 或 throw,finally 块都会执行(除非 JVM 强制退出或线程被中断)。
finally 是释放资源的“兜底保障”
finally 不替代正确设计,而是最后一道防线。它适合处理那些不能依赖 try-with-resources(比如老版本 JDK 或非 AutoCloseable 类型资源)或需要额外清理逻辑(如重置状态、记录日志)的场景。
- 即使
try中return,finally仍会先执行再返回 - 即使
catch中再次抛出异常,finally也会执行 - 若
finally自己抛出异常,会覆盖try或catch中的异常(需谨慎)
典型写法:手动 close + null 检查
以 FileInputStream 为例(Java 7 之前常用方式):
FileInputStream fis = null;
try {
fis = new FileInputStream("data.txt");
// 读取操作...
} catch (IOException e) {
// 处理异常
} finally {
if (fis != null) {
try {
fis.close(); // 可能抛 IOException,需再捕获
} catch (IOException e) {
// 记录关闭失败,但不打断主流程
System.err.println("关闭流失败:" + e.getMessage());
}
}
}关键点:
- 资源声明在 try 外,保证 finally 可访问
- null 检查避免空指针
- 关闭本身也需 try-catch,防止关闭异常干扰主逻辑
注意 return 和 finally 的执行顺序
如果 try 或 catch 中有 return,JVM 会暂存返回值,先执行 finally,再真正返回。例如:
将后端 Java 接口文档转换为前端 TypeScript 类型定义(interface / type)。输入:飞书文档、Spring Boot 接口文档、Swagger/OpenAPI、手写 API 文档等。输出:包含请求参数与响应结果的 .md 文件,含完整 JSDoc 注释。触发关键词:Java 转 TS、接口转换、生成前端类型、接口文档转 TypeScript、DTO/VO/BO 转 interface、后端文档转前端类型、生成接口类型、类型定义生成。
立即学习“Java免费学习笔记(深入)”;
public static int getValue() {
int x = 0;
try {
return x++; // 此时返回值已确定为 0
} finally {
x++; // 这里 x 变成 2,但不影响已暂存的返回值
}
}结果是返回 0,不是 2。所以不要在 finally 中修改影响返回值的变量。
更推荐:优先用 try-with-resources(Java 7+)
对于实现了 AutoCloseable 的资源(绝大多数标准 I/O 类都支持),应优先使用 try-with-resources:
try (FileInputStream fis = new FileInputStream("data.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
// 使用资源
} catch (IOException e) {
// 异常处理
} // 自动按声明逆序调用 close(),无需 finally它比手写 finally 更简洁、安全,且支持多个资源自动管理。只有当资源不满足 AutoCloseable,或需在关闭后做其他操作(如清理临时文件、释放锁)时,才回归 finally。

















