使用枚舉定義常量時,會伴有大量的switch語句判斷,目的是偽類每個枚舉項解釋其行為,例如:
1 public class Client { 2 public static void main(String[] args) { 3 4 doSports(null); 5 } 6 7 public static void doSports(Season season) { 8 switch (season) { 9 case Spring: 10 System.out.println("春天放風箏"); 11 break; 12 case Summer: 13 System.out.println("夏天游泳"); 14 break; 15 case Autumn: 16 System.out.println("秋天捉知了"); 17 break; 18 case Winter: 19 System.out.println("冬天滑冰"); 20 break; 21 default: 22 System.out.println("輸入錯誤!"); 23 break; 24 } 25 } 26 } 27 28 enum Season { 29 Spring, Summer, Autumn, Winter; 30 }
上面的代碼輸入 了一個Season類型的枚舉,然后使用switch進行匹配,目的是輸出每個季節的活動.但是代碼是否有問題?
doSports(null),似乎會打印出"輸出錯誤",因為在switch中沒有匹配到指定的值,所以會打印出default的代碼塊.
運行看結果:
Exception in thread "main" java.lang.NullPointerException at cn.summerchill.test.Client.doSports(Client.java:12) at cn.summerchill.test.Client.main(Client.java:8)
switch那一行報出了空指針...這就是枚舉和switch的特性有關了...此問題也是在開發中經常發生.
目前Java中的switch語句只能判斷byte,short,char,int類型(JDK7中已經允許使用String類型),這是Java編譯器的限制,問題是為什么枚舉類型也可以 跟在switch后面呢?
因為編譯時,編譯器判斷出switch語句后面的參數是枚舉類型,然后就根據枚舉的排序值繼續匹配,也就是說上面代碼與以下代碼相同:
public class Client { public static void main(String[] args) { doSports(Season.Spring); } public static void doSports(Season season) { switch (season.ordinal()) { case Season.Spring.ordinal(): System.out.println("春天放風箏"); break; case Season.Summer.ordinal(): System.out.println("夏天游泳"); break; case Season.Autumn.ordinal(): System.out.println("秋天捉知了"); break; case Season.Winter.ordinal(): System.out.println("冬天滑冰"); break; default: System.out.println("輸入錯誤!"); break; } } } enum Season { Spring, Summer, Autumn, Winter; }
但是這樣會報錯的...在各個case語句上 報 case expressions must be constant expressions..但是書中卻沒有提到這一點....不知道為什么.....
switch語句是先計算season變量的排序值,然后與枚舉常量的每個排序值進行對比.
在我們的例子中season的變量值是null,無法執行ordinal()方法,於是報空指針異常了.
解決方法也有很簡單:在doSports()方法中判斷輸入的參數是否是null即可.
ordinal 單詞是序數的意思. ordinal()方法獲得的是從0開始的數字 .....Spring對應為0 ,Summer為1,Autumn為2,Winter為3