finally代码块确保无论是否发生异常都会执行,用于资源清理;必须跟在try后,可接catch,遇return/break/continue仍执行,但system.exit()会跳过;推荐用try-with-resources替代手动finally。

在 Java 中,finally 代码块用于确保无论是否发生异常,其中的代码都会被执行。它通常与 try 和可选的 catch 配合使用,是资源清理(如关闭文件、释放连接)的关键位置。
finally 的基本写法和执行时机
finally 必须跟在 try 块之后,可以放在 catch 块之后(如果有),也可以直接跟在 try 后面(无 catch)。只要 try 或 catch 块开始执行,finally 就一定会运行——哪怕遇到 return、break、continue,甚至未捕获的异常也会触发它。
- 即使
try中有return,也会先执行finally再返回(但注意:若finally也含return,会覆盖之前的返回值) -
finally不会在 JVM 强制退出(如System.exit())时执行 - 不建议在
finally中抛出新异常或写return,容易掩盖原始问题
典型应用场景:资源安全释放
最常见的用途是释放外部资源。例如打开一个 FileInputStream,必须确保关闭,否则可能造成句柄泄漏。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
FileInputStream fis = null;
try {
fis = new FileInputStream("data.txt");
// 读取操作
} catch (IOException e) {
System.err.println("读取失败:" + e.getMessage());
} finally {
if (fis != null) {
try {
fis.close(); // 关闭前判空,避免 NullPointerException
} catch (IOException e) {
System.err.println("关闭流时出错:" + e.getMessage());
}
}
}
- 先判空再关闭,防止
NullPointerException - 关闭本身也可能抛异常,需单独捕获,不能让它中断
finally流程 - Java 7+ 更推荐用 try-with-resources(自动管理资源),它隐式包含类似
finally的清理逻辑
try-with-resources 替代方案(更简洁安全)
如果资源实现了 AutoCloseable 接口(如 InputStream、Connection、Scanner),优先使用 try-with-resources:
try (FileInputStream fis = new FileInputStream("data.txt");
BufferedReader reader = new BufferedReader(new InputStreamReader(fis))) {
String line = reader.readLine();
System.out.println(line);
} catch (IOException e) {
System.err.println("操作失败:" + e.getMessage());
}
// fis 和 reader 会自动关闭,无需手动写 finally
- 资源在
try括号内声明,作用域受限,自动调用close() - 即使发生异常,所有资源仍按声明逆序关闭
- 底层原理仍是编译器生成等效的
finally调用,但更安全、简洁、不易出错
注意事项和常见误区
finally 很有用,但滥用或误用反而引入风险:
- 不要在
finally中修改影响业务逻辑的变量(尤其与return相关的值) - 避免在
finally中写耗时操作(如网络请求、大循环),它会拖慢异常处理路径 - 当
try和finally都有return时,finally的return总是生效,原异常或返回值会被丢弃 - 多层嵌套时,每个
try对应自己的finally,注意作用范围
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










