參考部落格:
https://www.cnblogs.com/balingybj/p/5751707.html
Switch的思考
Switch與If--else的比較
switch...case與if...else的根本區別在於,
switch...case會生成一個跳轉表來指示實際的case分支的地址,而這個跳轉表的索引號與switch變數的值是相等的。從而,switch...case不用像if...else那樣遍歷條件分支直到命中條件,而只需訪問對應索引號的表項從而到達定位分支的目的。
具體地說:
- switch...case會生成一份大小(表項數)為最大case常量+1的跳錶,
- 程式首先判斷switch變數是否大於最大case 常量,若大於,則跳到default分支處理;
- 否則取得索引號為switch變數大小的跳錶項的地址(即跳錶的起始地址+表項大小*索引號)(類似與ArrayList實現了RandomAccess隨機訪問介面)
- 程式接著跳到此地址執行,到此完成了分支的跳轉。
由此看來,switch有點以空間換時間的意思,而事實上也的確如此。
1.當分支較多時,當時用switch的效率是很高的。因為switch是隨機訪問的,就是確定了選擇值之後直接跳轉到那個特定的分支,但是if...else是遍歷所以得可能值,知道找到符合條件的分支。如此看來,switch的效率確實比ifelse要高的多。
2.由上面的彙編程式碼可知道,switch...case佔用較多的程式碼空間,因為它要生成跳錶,特別是當case常量分佈範圍很大但實際有效值又比較少的情況,switch...case的空間利用率將變得很低。
3.switch...case只能處理case為常量的情況,對非常量的情況是無能為力的。例如 if (a > 1 && a < 100),是無法使用switch...case來處理的。所以,switch只能是在常量選擇分支時比ifelse效率高,但是ifelse能應用於更多的場合,ifelse比較靈活。
JDK1.5 switch中列舉(Enum)的使用
JDK1.5 之前,switch語句支援的資料型別有byte、short、int、char.
在JDK1.5之後,增加了列舉型別,列舉型別可以對狀態常量進行統一的整理,並且新增基本屬性。
列舉也可以更在Sewitch後面,原因是switch先計算變數的排序值,然後與列舉常量的每個排序值進行對比,當變數為空時,呼叫ordinal方法報空指標異常。所以對於安全性要求高的程式碼需要判斷。
switch(s) =s.ordinal;
jdk1.7 Switch中Spring的使用
在Java 7中,增加了對String型別的支援:實現的機制是根據字串的雜湊值匹配。下圖是原檔案編譯前,和編譯後,
Java和class檔案的對比。
可以看出將字串的switch轉換為兩個switch處理,通過雜湊值匹配到資料,通過定義的byte變數在swit到具體的程式碼快執行。