finally块必定执行的核心在于javascript引擎在跳转操作“落地前”强制插入执行,即在try/catch中return/throw后暂存结果、交还控制权前执行;但process.exit()或引擎崩溃时会被跳过。

finally 块能“保证必定执行”,核心在于 JavaScript 引擎对控制流的底层调度机制——它被设计为在 try 或 catch 中的 return、throw、break、continue 等跳转操作完成之后、但控制权尚未交还给调用者之前,强制插入执行。
执行时机:在跳转“落地前”拦截
无论 try 块中发生什么,只要进入 try(哪怕只执行了一行),引擎就会为 finally 预留一个“收尾执行点”:
- 正常执行完 try → 立即跳转到 finally
- try 中 throw 错误且有 catch → 先执行 catch,再执行 finally
- try 中 throw 错误但无匹配 catch → 在错误向上抛出前,先执行 finally
- try 或 catch 中有 return → 先计算 return 后的表达式(如
return obj.name),把返回值暂存,然后执行 finally,最后才把暂存值真正返回
不依赖异常捕获,只依赖语句结构
finally 不需要 catch 存在也能工作。单独的 try/finally 是合法语法,适用于你只想做清理、但不想吞掉错误的场景:
- 比如发起网络请求后必须关闭 loading 状态,但错误仍要抛给上层统一处理
- 比如打开文件后必须确保 close() 被调用,哪怕读取过程直接报错退出
例外情况:极少数会跳过 finally
“必定执行”不是绝对的,以下两种情况会导致 finally 被跳过:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 调用
self.close()(浏览器环境)或process.exit()(Node.js)等进程/页面级强制终止操作 - 运行时发生致命错误(如内存溢出、栈溢出),导致 JS 引擎崩溃
日常业务代码中,这两种情况几乎不会主动触发,所以实践中可视为“必定执行”。
注意:finally 中 return 会劫持结果
如果 finally 自身包含 return、throw 或循环控制语句(如 break),它会覆盖 try/catch 的返回值或错误:
-
try { return 'a'; } finally { return 'b'; }→ 实际返回 'b' -
try { throw new Error('x'); } finally { return 'ok'; }→ 错误被静默吞掉,返回 'ok'
因此,除非有明确意图,否则避免在 finally 中写 return 或 throw。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










