finally的执行
finally不是百分百都执行。finally一般在try内的最后执行,一般用来释放资源用。
finally不执行的情况:
- try没执行的话,自然不会执行finally
- 遇到虚拟机中断,则finally不执行。System.exit(1);会中止当前运行中的jvm
- 非守护线程中止时,则守护线程里的finally不会被执行。
2013年的时候,与项目组里的架构师讨论程序设计时,有提到finally里资源释放的问题,他说自己的程序不会因任何意外而产生问题。当时,我只是硬生生的拿质量管理里的6西格玛理论跟他辩驳,却没有说服他。人的认知是在不断拓展的。近期,这位架构师,已经出书了,把自研的数据控制框架结合阴阳八卦学整理成册,看了其中一段,感觉很有道理。
ClassCastException
对于类继承,派生类拥有基类的所有成员,意思为:派生类 is a 基类。假如AVo extends BaseVo,则当 BaseVo clz=new AVo();时,clz可以转换成AVo。而 (AVo)new BaseVo() 这种转换,就会引发ClassCastException。
当一个基类有多个派生类时,在做类型转换时,可以先用instanceof来判断一下,以规避ClassCastException。
“没有”与“没有找到”是两回事!
运营反馈了一个bug。转正不久的程序媛排查了一段时间,然后郁闷地过来找我,信誓旦旦的说没有相关逻辑,疑惑不解的是为什么会出现运营所反馈的bug。是呀!如果没有相应的逻辑,不应该出现那样的bug。迟疑一会,然后,我跟她一起梳理代码,果然,发现了出错的代码段。找到了出错的地方,自然就好修复了。
“没有”与“没有找到”可不是一回事。这位女同学因为没有找到,而下结论为没有,这么一个心理暗示,导致了自己越来越迷糊。尽早丢掉这样的“多米诺骨牌”,不管做什么事情,专著和耐心是你乘风破浪的双翼。
我的代码绝对不会出错
产品汪跑到技术这边,说企业配置的数据不对,然后描述了一下企业的操作过程。程序猿小哥表示不接受,随即在测试环境模拟操作了一遍,没有复现出来。就反驳产品汪,并义正言辞的强调自己的程序不会有那样的问题,绝对不会。产品汪灰溜溜的走了。过了一会,又回来了,在生产环境,同样的问题又出现了。 我们只得细心地逐行排查代码来定位求证,果然,还真发现问题了。
墨菲定律是经得起考验的。永远不要认为100%没问题。别人指出了问题,先反思一下自己,也许更靠谱。
for循环里要不要捕获异常
我们知道,在循环一个集合数据时,一旦处理某条数据出现异常,那么,整个循环将会中断。
那么,在遍历集合数据时,有必要加一个异常捕获,即使某一条出异常,不会导致整个循环中断。就像下面的伪代码。对于一些定时任务,通常这么做比较靠谱。比如定期调用三方接口查询当前支付中交易的支付结果。
不过,要注意了,这样做并非放之四海而皆准。有些场景,却需要一旦出现异常就要中断整个循环。
譬如,合并支付的场景,多条业务单对应一笔支付单。当支付单支付成功后,要修改对应的业务单状态。如果使用for循环来逐条修改的话,就不能在循环体里加异常捕获。这是一个完整的事务,要么都改,要么都不改。
for (Entity entity : list){ try { ..业务处理.. } catch(Exception e){ log.error("当前数据处理异常,", e); } }