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);
}
}