讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議15:break萬萬不可忘 >

建議15:break萬萬不可忘

我們經常會寫一些轉換類,比如貨幣轉換、日期轉換、編碼轉換等,在金融領域裡用到最多的要數中文數字轉換了,比如把「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直接就報個紅叉給你看,這樣就可以完全避免該問題的發生了。