天天看點

為什麼在Java7中Switch語句支援String而不支援long呢?Switch語句長啥樣?Switch支援字元以及字元串的底層原理為什麼不支援long類型呢?

目錄

Switch語句長啥樣?

Switch支援字元以及字元串的底層原理

為什麼不支援long類型呢?

Switch語句長啥樣?

public static void main(String[] args) {
        int num = 1;
        switch (num) {
            case 1:
                System.out.println("a");
                break;
            case 2:
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }
    }
           

JDK7之前支援的類型隻有byte、short、char、int、integer、enum類型。而在JDK7時終于對字元串類型進行了适配。

Switch支援字元以及字元串的底層原理

對于如下這段代碼,對其進行反編譯

public class SwitchTest {
    public static void main(String[] args) {
        char ch = 'a';
        switch (ch) {
            case 'a':
                System.out.println("a");
                break;
            case 'b':
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

        String str = "a";
        switch (str) {
            case "a":
                System.out.println("a");
                break;
            case "b":
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }
    }

}
           

反編譯代碼如下:

public class SwitchTest {
    public SwitchTest() {
    }

    public static void main(String[] args) {
        char ch = 97;
        switch (ch) {
            case 97:
                System.out.println("a");
                break;
            case 98:
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

        switch ("a") {
            case "a":
                System.out.println("a");
                break;
            case "b":
                System.out.println("b");
                break;
            default:
                System.out.println("c");
        }

    }
}
           
可以看到對于字元類型來說,底層實際上比較的是 ascii 碼,編譯器會把char型變量轉換成對應的 int 型變量。但發現字元串類型沒有變化,難不成是完美适配?【不存在的,僅僅是因為部落客的idea或者是jdk版本的問題沒有看到它的真實面貌】

借用其它部落客的case,代碼如下:

public class switchDemoString {
    public static void main(String[] args) {
        String str = "world";
        switch (str) {
        case "hello":
            System.out.println("hello");
            break;
        case "world":
            System.out.println("world");
            break;
        default:
            break;
        }
    }
}
           

上述反編譯後如下所示:

public class switchDemoString
{
    public switchDemoString()
    {
    }
    public static void main(String args[])
    {
        String str = "world";
        String s;
        switch((s = str).hashCode())
        {
        default:
            break;
        case 99162322:
            if(s.equals("hello"))
                System.out.println("hello");
            break;
        case 113318802:
            if(s.equals("world"))
                System.out.println("world");
            break;
        }
    }
}
           
這下可以知道原來字元串的 switch 是通過 equals() 和 hashCode() 方法來實作的。請記住,switch中隻能使用整型,比如byte、short、char 以及 int。仔細看下可以發現,switch 塊中實際是哈希值,然後通過使用 equals 方法比較進行安全檢查,這個檢查是必要的,因為哈希可能會發生碰撞。是以它的性能是不如使用枚舉進行 switch 或者使用純整數常量。Java編譯器隻增加了一個 equals 方法,如果你比較的是字元串字面量的話會非常快,比如”abc” ==”abc”。如果你把 hashCode() 方法的調用也考慮進來了,那麼還會再多一次的調用開銷。因為字元串一旦建立了,它就會把哈希值緩存起來。是以如果這個 switch 語句是用在一個循環裡的,比如逐項處理某個值,或者遊戲引擎循環地渲染螢幕,這裡hashCode()方法的調用開銷其實不會很大。

為什麼不支援long類型呢?

在 stackoverflow 網站上也有人提出同樣的問題

為什麼在Java7中Switch語句支援String而不支援long呢?Switch語句長啥樣?Switch支援字元以及字元串的底層原理為什麼不支援long類型呢?

挑選出熱度最高的評論

為什麼在Java7中Switch語句支援String而不支援long呢?Switch語句長啥樣?Switch支援字元以及字元串的底層原理為什麼不支援long類型呢?
翻譯過來大緻意思是,因為 switch 的設計初衷是對那些隻有少數的幾個值進行等值判斷,如果值過于複雜,那麼還是用 if 比較合适。

參考連結:

jdk7 switch 對 String 的支援 - 之石先生 - 部落格園

Why can't your switch statement data type be long, Java? - Stack Overflow