JDK | Switch對String的支持

Java 7中,switch的參數可以是String類型了,這對我們來說是一個很方便的改進。到目前爲止switch支持這樣幾種數據類型:byte short int char String 。但是,作爲一個程序員我們不僅要知道他有多麼好用,還要知道它是如何實現的,switch對整型的支持是怎麼實現的呢?對字符型是怎麼實現的呢?String類型呢?有一點Java開發經驗的人這個時候都會猜測switch對String的支持是使用equals()方法和hashcode()方法。那麼到底是不是這兩個方法呢?接下來我們就看一下,switch到底是如何實現的。

一、switch對整型支持的實現

下面是一段很簡單的Java代碼,定義一個int型變量a,然後使用switch語句進行判斷。執行這段代碼輸出內容爲5,那麼我們將下面這段代碼反編譯,看看他到底是怎麼實現的。

public class switchDemoInt {
    public static void main(String[] args) {
        int a = 5;
        switch (a) {
        case 1:
            System.out.println(1);
            break;
        case 5:
            System.out.println(5);
            break;
        default:
            break;
        }
    }
}
//output 5

反編譯後的代碼如下:

public class switchDemoInt
{
    public switchDemoInt()
    {
    }
    public static void main(String args[])
    {
        int a = 5;
        switch(a)
        {
        case 1: // '\001'
            System.out.println(1);
            break;

        case 5: // '\005'
            System.out.println(5);
            break;
        }
    }
}

我們發現,反編譯後的代碼和之前的代碼比較除了多了兩行註釋以外沒有任何區別,那麼我們就知道,switch對int的判斷是直接比較整數的值

二、switch對字符型支持的實現

直接上代碼:

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

編譯後的代碼如下: `public class switchDemoChar

public class switchDemoChar
{
    public switchDemoChar()
    {
    }
    public static void main(String args[])
    {
        char a = 'b';
        switch(a)
        {
        case 97: // 'a'
            System.out.println('a');
            break;
        case 98: // 'b'
            System.out.println('b');
            break;
        }
  }
}

通過以上的代碼作比較我們發現:對char類型進行比較的時候,實際上比較的是ascii碼,編譯器會把char型變量轉換成對應的int型變量

三、switch對字符串支持的實現

還是先上代碼:

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中只能使用整型,比如byteshortchar(ackii碼是整型)以及int。還好hashCode()方法返回的是int,而不是long。通過這個很容易記住hashCode返回的是int這個事實。仔細看下可以發現,進行switch的實際是哈希值,然後通過使用equals方法比較進行安全檢查,這個檢查是必要的,因爲哈希可能會發生碰撞。因此它的性能是不如使用枚舉進行switch或者使用純整數常量,但這也不是很差。因爲Java編譯器只增加了一個equals方法,如果你比較的是字符串字面量的話會非常快,比如”abc” ==”abc”。如果你把hashCode()方法的調用也考慮進來了,那麼還會再多一次的調用開銷,因爲字符串一旦創建了,它就會把哈希值緩存起來。因此如果這個switch語句是用在一個循環裏的,比如逐項處理某個值,或者遊戲引擎循環地渲染屏幕,這裏hashCode()方法的調用開銷其實不會很大。

好,以上就是關於switch對整型、字符型、和字符串型的支持的實現方式,總結一下我們可以發現,其實switch只支持一種數據類型,那就是整型,其他數據類型都是轉換成整型之後在使用switch的。

 

轉自:https://github.com/hollischuang/toBeTopJavaer/blob/master/basics/java-basic/switch-string.md

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章