孤舟笔记 基础篇十五 finally 不是永远执行的吗?这些情况它真的不会执行
文章目录一、先说结论finally 几乎一定执行但不是绝对二、正常情况finally 确实很靠谱三、不执行的情况finally 也无力回天1. System.exit()——JVM 关机谁也拦不住2. 无限循环/死锁——永远到不了 finally3. 守护线程——JVM 退出时直接被抛弃4. kill -9——操作系统直接砍进程四、finally 的另一个坑return 覆盖五、回到全貌一图记住六、回答技巧与点评标准回答加分回答面试官点评个人网站面试官问你finally 语句块一定会执行吗你脱口而出一定面试官笑了“确定”你开始慌了。不是叫 finally 吗finally 不就是最终的意思吗最终执行那不是一定的吗还真不是。finally 有几种情况真的不会执行而且其中一些你可能在工作中已经踩过坑只是没意识到。一、先说结论finally 几乎一定执行但不是绝对情况finally 是否执行正常执行 try✅ 执行try 中抛异常✅ 执行try 中 return✅ 执行return 前先执行 finallytry 中有 returnfinally 也有 return✅ 执行但 finally 的 return 会覆盖 try 的System.exit()❌ 不执行JVM 直接关了无限循环/死锁❌ 不执行永远到不了 finally守护线程中 JVM 退出❌ 不执行线程被直接干掉强行杀进程kill -9❌ 不执行操作系统层面干掉了一句话记住finally 挡得住异常挡不住 JVM 关机。二、正常情况finally 确实很靠谱先看 finally 的基本盘——绝大多数情况下它确实会执行// 情况1正常执行try{System.out.println(try);}finally{System.out.println(finally);// ✅ 执行}// 情况2抛异常try{thrownewException(炸了);}finally{System.out.println(finally);// ✅ 执行}// 情况3try 里有 returntry{return;}finally{System.out.println(finally);// ✅ 执行return 之前先跑 finally}这三种情况覆盖了日常开发的 99%所以很多人形成了finally 一定执行的印象。但面试考的就是那 1%。三、不执行的情况finally 也无力回天1. System.exit()——JVM 关机谁也拦不住try{System.out.println(try);System.exit(0);// JVM 直接退出}finally{System.out.println(finally);// ❌ 不会执行}System.exit()是拔电源级别的操作——JVM 都关了还执行什么 finally就像你正要锁门出门结果房子塌了门还锁个啥。这也是为什么说 finally 挡不住 JVM 关机。System.exit(0)是正常退出System.exit(1)是异常退出不管哪个JVM 都直接走人。2. 无限循环/死锁——永远到不了 finallytry{while(true){// 死循环// 永远出不去}}finally{System.out.println(finally);// ❌ 永远执行不到}finally 的前提是 try 块结束不管是正常结束还是异常结束。如果 try 根本结束不了finally 自然没机会上场。就像排队等下班打卡但你永远在加班那下班卡永远打不上。3. 守护线程——JVM 退出时直接被抛弃ThreaddaemonnewThread(()-{try{System.out.println(守护线程try);}finally{System.out.println(守护线程finally);// ❌ 可能不执行}});daemon.setDaemon(true);// 设置为守护线程daemon.start();// 主线程结束后 JVM 退出守护线程的 finally 不会执行守护线程是给用户线程打辅助的。当所有用户线程结束JVM 就要退出守护线程会被直接干掉不管你 finally 里写了什么。所以千万别在守护线程的 finally 里做资源释放靠不住。4. kill -9——操作系统直接砍进程这个不用代码演示了。你在服务器上kill -9强杀 Java 进程操作系统直接回收内存JVM 连善后的机会都没有finally 自然不会执行。四、finally 的另一个坑return 覆盖finally 不止执不执行有坑怎么执行也有坑publicstaticinttest(){try{return1;}finally{return2;// finally 的 return 覆盖了 try 的 return}}// 返回 2不是 1千万不要在 finally 里写 return它不仅会覆盖 try 的返回值还会吞掉 try 里的异常publicstaticinttest(){try{thrownewRuntimeException(炸了);}finally{return2;// 异常被吞了调用方完全不知道出过错}}// 返回 2异常消失了调用方无感知finally 里的 return 就像开会时领导最后总结——不管你前面说了啥领导说的才是最终结论你的话全白说。五、回到全貌一图记住finally 执行情况 ├── ✅ 一定执行正常、异常、try 有 return └── ❌ 不执行 ├── System.exit() → JVM 关机 ├── 死循环/死锁 → 永远到不了 ├── 守护线程 JVM 退出 → 直接被抛弃 └── kill -9 → 操作系统强杀 finally 的坑 ├── finally 里的 return 会覆盖 try 的 return └── finally 里的 return 会吞掉 try 的异常 口诀finally 挡得住异常挡不住关机 finally 别写 return写了覆盖又吞异常。六、回答技巧与点评标准回答finally 语句块在绝大多数情况下会执行包括 try 正常结束、抛异常、甚至 try 中有 return 时都会在 return 之前执行 finally。但在以下情况不会执行调用了 System.exit() 导致 JVM 退出、try 中存在无限循环或死锁导致永远无法退出、守护线程中 JVM 退出时线程被直接终止、操作系统强杀进程。另外需要注意finally 中不要写 return 语句它会覆盖 try 的返回值并吞掉异常。加分回答提到 try-with-resourcesJava 7 引入的 try-with-resources 比 finally 关闭资源更安全因为它会保留原始异常不会被 finally 中的异常覆盖提到 finally 执行时机finally 在 try 的 return 之前执行但 return 的值在 finally 执行前就已经确定了除非 finally 修改了引用类型的字段提到实际建议资源释放优先用 try-with-resources别在 finally 里写 return守护线程的清理逻辑别放 finally面试官点评这道题是经典坑题考的是你对 JVM 运行机制的理解。finally 一定执行是大多数人脱口而出的答案但能说出 System.exit() 和守护线程两种不执行的情况就说明你比一般人深了一层。如果能再提到 finally 中 return 的坑和 try-with-resources 的最佳实践面试官会认为你不仅懂原理还知道怎么避坑这是加分项。原文阅读内容有帮助点赞、收藏、关注三连评论区等你
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2557071.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!