finally 中的 return 会直接返回其值,忽略 try/catch 的 return;system.exit() 或线程强制终止时 finally 不执行;优先用 try-with-resources 关流;多异常捕获需子类在前;finally 抛异常会吞掉原异常。

try-catch-finally 里 return 语句怎么被覆盖
当 try 或 catch 块中有 return,而 finally 里也有 return,最终返回的是 finally 的值——不是“覆盖”逻辑,而是 JVM 在执行 finally 前会暂存 try/catch 的返回值,但一旦 finally 自己 return,就直接跳过原返回路径。
-
finally中有return时,try或catch中的return不会生效(连副作用都可能被截断,比如日志没打完) - 如果
finally没有return,但修改了引用类型变量的内容(如list.add()),调用方仍能看到修改;但对基本类型或重新赋值(i = 5)无效 - 避免在
finally中写return,它会让方法行为难以追踪,尤其在封装工具类时容易引发静默逻辑错误
finally 一定会执行吗?哪些情况它会被跳过
绝大多数情况下 finally 都会执行,但有两个硬性例外:JVM 直接退出,或当前线程被强制中断且未恢复。
-
System.exit(0)会立即终止 JVM,跳过所有finally - 线程执行到
try时被Thread.stop()(已废弃)或Runtime.halt()终止,finally不触发 -
finally不是“万能兜底”——它不捕获异常,也不处理线程死亡、OOM 导致的进程崩溃等底层故障 - 不要在
finally里放关键资源释放逻辑以外的代码,比如发通知、更新状态,否则可能漏执行
try-with-resources 和 finally 谁更适合关流
优先用 try-with-resources,它本质是编译器自动插入 finally 调用 close(),但更安全、更简洁。
-
try-with-resources要求资源实现AutoCloseable,且会在异常传播前确保close()执行(即使try块抛出异常) - 手动写
finally关流容易漏判null、重复关闭、或在close()抛异常时掩盖原异常(需用addSuppressed()) - 如果必须用
finally(比如老 JDK 或非AutoCloseable资源),记得先判空再关,并把close()包在独立try-catch里
catch 多个异常时,顺序错了会编译失败
子类异常必须写在父类异常前面,否则编译报错:error: exception XXX has already been caught。
- 比如同时 catch
IOException和FileNotFoundException,后者必须在前,因为它是前者的子类 - Java 7+ 支持多异常捕获语法:
catch (IOException | SQLException e),此时它们必须是并列关系(无继承),否则编译不过 - 别为了“省事”把
Exception写最前——它会吃掉所有后续catch,让具体异常处理逻辑失效
真正容易被忽略的,是 finally 里抛出异常会吞掉 try 或 catch 中原本要抛的异常。除非你明确想压制原异常,否则 finally 应该只做清理,不抛、不返、不改状态。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











