我们经常会写一些转换类,比如货币转换、日期转换、编码转换等,在金融领域里用到最多的要数中文数字转换了,比如把“1”转换为“壹”,不过,开源世界是不会提供此工具类的,因为它太贴合中国文化了,要转换还是得自己动手写,代码片段如下:
public class Client{
public static void main(Stringargs){
System.out.println("2="+toChineseNumberCase(2));
}
//把阿拉伯数字翻译成中文大写数字
public static String toChineseNumberCase(int n){
String chineseNumber="";
switch(n){
case 0:chineseNumber="零";
case 1:chineseNumber="壹";
case 2:chineseNumber="贰";
case 3:chineseNumber="叁";
case 4:chineseNumber="肆";
case 5:chineseNumber="伍";
case 6:chineseNumber="陆";
case 7:chineseNumber="柒";
case 8:chineseNumber="捌";
case 9:chineseNumber="玖";
}
return chineseNumber;
}
}
这是一个简单的转换类,并没有完整实现,只是一个金融项目片段。如此简单的代码应该不会有错吧,我们运行看看,结果是:2=玖。
恩?错了?回头再来看程序,马上醒悟了:每个case语句后面少加了break关键字。程序从"case 2"后面的语句开始执行,直到找到最近的break语句结束,但可惜的是我们的程序中没有break语句,于是在程序执行的过程中,chineseNumber的赋值语句会多次执行,会从等于“贰”、等于“叁”、等于“肆”,一直变换到等于“玖”,switch语句执行结束了,于是结果也就如此了。
此类问题发生得非常频繁,但也很容易发现,只要做一下单元测试(Unit Test),问题立刻就会被发现并解决掉,但如果是在一堆的case语句中,其中某一条漏掉了break关键字,特别是在单元测试覆盖率不够高的时候(为什么不够高?在大点的项目中蹲过坑、打过仗的兄弟们可能都知道,项目质量是与项目工期息息相关的,而项目工期往往不是由项目人员决定的,所以如果一个项目的单元测试覆盖率能够达到60%,你就可以笑了),也就是说分支条件可能覆盖不到的时候,那就会在生产中出现大事故了。
我曾遇到过一个类似的事故,那是开发一个通过会员等级决定相关费率的系统,由于会员等级有100多个,所以测试时就采用了抽样测试的方法,测试时一切顺利,直到系统上线后,财务报表系统发现一个小概率的会员费率竟然出奇的低,于是就跟踪分析,发现是少了一个break,此事不仅造成甲方经济上的损失,而且在外部也产生了不良的影响,最后该代码的作者被辞退了,测试人员、质量负责人、项目经理都做了相应的处罚。希望读者能引以为戒,记住在case语句后面随手写上break,养成良好的习惯。
对于此类问题,还有一个最简单的解决办法:修改IDE的警告级别,例如在Eclipse中,可以依次点击Performaces→Java→Compiler→Errors/Warnings→Potential Programming problems,然后修改'switch' case fall-through为Errors级别,如果你胆敢不在case语句中加入break,那Eclipse直接就报个红叉给你看,这样就可以完全避免该问题的发生了。