[改善Java代碼]小心switch帶來的空值異常


使用枚舉定義常量時,會伴有大量的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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM