finally块中代码必须安全执行,不得抛异常、写return或掩盖原始错误;应使用内层try-catch处理清理异常,或优先采用java 7+的try-with-resources自动管理资源。

finally块中的代码必须安全执行,不能干扰主流程的异常传播或返回逻辑。核心原则是:不抛异常、不写return、不掩盖原始错误。
避免在finally中主动抛出检查异常
如果清理操作(如close())可能失败,直接抛出异常会覆盖try/catch中已发生的异常,导致原始错误丢失。例如:
- try里发生
NullPointerException - catch记录日志但未重抛
- finally中
close()抛出IOException - 最终调用方只看到
IOException,完全不知最初空指针在哪
用内部try-catch包裹清理逻辑
对可能出错的清理语句单独加一层保护,异常在finally内部消化:
- 用
try { resource.close(); } catch (IOException e) { logger.warn("关闭资源失败", e); } - 不向外抛出,也不影响主异常链
- 适合手动管理资源的老版本Java(如Java 6及之前)
优先使用try-with-resources替代手写finally
Java 7+推荐方式,自动处理资源关闭与异常抑制:
- 声明资源时用
try (FileInputStream fis = new FileInputStream("a.txt")) { ... } - 即使try块和close()都抛异常,主异常仍为try中那个
- 关闭异常会作为
suppressed exception附加到主异常上,可通过e.getSuppressed()查看 - 语义清晰,无需手动写finally
finally中禁止出现return语句
一旦finally中有return,会直接终止方法,覆盖try或catch里的return值或异常:
- 即使try中写了
return 42;,finally里return -1;会让结果永远是-1 - 若try中已抛异常,finally的return会让异常彻底消失
- 所有清理工作应在无return的前提下完成
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











