讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議86:在switch的default代碼塊中增加AssertionError錯誤 >

建議86:在switch的default代碼塊中增加AssertionError錯誤

switch後跟枚舉類型,case後列出所有的枚舉項,這是一個使用枚舉的主流寫法,那留著default語句似乎沒有任何作用,程序已經列舉了所有的可能選項,肯定不會執行到default語句,看上去純屬多餘嘛!錯了,這個default還是很有用的。以我們定義的日誌級別來舉例說明,這是一個典型的枚舉常量,如下所示:


enum LogLevel{

DEBUG, INFO, WARN, ERROR;

}


一般在使用的時候,會通過swtich語句來決定用戶設置的級別,然後輸出不同級別的日誌,代碼如下:


switch(logLevel){

case DEBUG:

……

case INFO:

……

case WARN:

……

case ERROR:

……

}


由於把所有的枚舉項都列舉完了,不可能有其他值,所以就不需要default代碼塊了,這是普遍的認識,但問題是我們的switch代碼與枚舉之間沒有強制約束關係,也就是說兩者只是在語義上建立了聯繫,並沒有一個強制約束,比如LogLevel枚舉發生改變,增加了一個枚舉項FATAL,如果此時我們對switch語句不做任何修改,編譯雖不會出現問題,但是運行期會發生非預期的錯誤:FATAL類型的日誌沒有輸出。

為了避免出現這類錯誤,建議在default後直接拋出一個AssertionError錯誤,其含義就是「不要跑到這裡來,一跑到這裡就會出問題」,這樣可以保證在增加一個枚舉項的情況下,若其他代碼未修改,運行期馬上就會報錯,這樣一來就很容易查找到錯誤,方便立刻排除。

當然也有其他方法解決此問題,比如修改IDE工具,以Eclipse為例,可以把Java→Compiler→Errors/Warnings中的"Enum type constant not covered on' switch'"設置為Error級別,如果不判斷所有的枚舉項就不能通過編譯。