最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java switch關(guān)鍵字原理及用法詳解

 更新時間:2019年11月11日 16:51:16   作者:逸游Java  
這篇文章主要介紹了Java中 switch關(guān)鍵原理及用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

這篇文章主要介紹了Java中 switch關(guān)鍵原理及用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

Switch語法

switch作為Java內(nèi)置關(guān)鍵字,卻在項目中真正使用的比較少。關(guān)于switch,還是有那么一些奧秘的。

要什么switch,我有if-else

確實,項目中使用switch比較少的一個主要原因就在于它的作用能被if-else代替,況且switch對類型的限制,也阻礙了switch的進一步使用。

先看看switch的語法:

switch(exp){
 case exp1:
  break;
 case exp2:
  break;
 default:
  break;
}

其中exp的類型限制為:byte ,short , int , char,及其包裝類,以及枚舉和String(JDK1.7)

為什么要有這些限制?

如果說,switch的功能和if-else的一模一樣,那么它存在的意義在哪里?

答案是:switch和if-else在設(shè)計的時候,是有一定的性能差別的。

看代碼:

public class Test {
 public static void switchTest(int a) {
  switch (a) {
   case 1:
    System.out.println("1");
    break;
   case 2:
    System.out.println("2");
    break;
   default:
    System.out.println("3");
    break;
  }
 }
}
javap -c Test.class

結(jié)果如下:

 public static void switchTest(int);
 Code:
  0: iload_0
  1: lookupswitch { // 2
      1: 28
      2: 39
    default: 50
   }
   
 ...

這里面省略一些代碼。

可以發(fā)現(xiàn),switch是通過lookupswitch指令實現(xiàn)。那么lookupswitch指令是干嘛的呢?

Java se8文檔中的描述可以大概知道:

switch可以被編譯為兩種指令

  • lookupswitch:當switch的case比較稀疏的時候,使用該指令對int值的case進行一一比較,直至找到對應(yīng)的case(這里的查找,可以優(yōu)化為二分查找)
  • tableswitch:當switch的case比較密集的時候,使用case的值作為switch的下標,可以在時間復(fù)雜度為O(1)的情況下找到對應(yīng)的case(可以類比HashMap)

并且文檔中還有一段描述:

Java虛擬機的tableswitch和 lookupswitch指令僅對int數(shù)據(jù)有效。因為對 byte,char或或short值的操作在內(nèi)部被提升為int,所以對其switch表達式求值為其中一個類型進行編譯,就好像它被計算為要鍵入一樣int。如果 chooseNear方法是使用type編寫的,則使用類型時 short將生成相同的Java虛擬機指令int。其他數(shù)字類型必須縮小到類型int 以便在a中使用switch。

現(xiàn)在,我們應(yīng)該能夠明白,為什么switch關(guān)鍵字會有類型限制了,因為 switch所被翻譯的關(guān)鍵字是被限制為int類型的,至于為什么是int,我猜應(yīng)該是基于性能和實現(xiàn)的復(fù)雜度的考量吧。

int之外的類型

我們明白了byte,shor,char,int能被作為switch類型后,再看看枚舉和String

public static void switchTest(String a) {
  switch (a) {
   case "1":
    System.out.println("1");
    break;
   case "2":
    System.out.println("2");
    break;
   default:
    System.out.println("3");
    break;
  }
 }

編譯生成Test.class。拖入IDEA進行反編譯得到如下代碼:

 public static void switchTest(String a) {
  byte var2 = -1;
  switch(a.hashCode()) {
  case 49:
   if (a.equals("1")) {
    var2 = 0;
   }
   break;
  case 50:
   if (a.equals("2")) {
    var2 = 1;
   }
  }
  switch(var2) {
  case 0:
   System.out.println("1");
   break;
  case 1:
   System.out.println("2");
   break;
  default:
   System.out.println("3");
  }
 }

可以看見,JDK7 所支持的String類型是通過獲取String的hashCode來進行選擇的,也就是本質(zhì)上還是int.為什么String可以這樣干?這取決于String是一個不變類。

為了防止hash碰撞,代碼更加保險的進行了equals判斷。

再來看看Enum

public static void switchTest(Fruit a) {
 switch (a) {
  case Orange:
   System.out.println("Orange");
   break;
  case Apple:
   System.out.println("Apple");
   break;
  default:
   System.out.println("Banana");
   break;
 }
}

編譯生成Test.class。拖入IDEA進行反編譯得到如下代碼:

 public static void switchTest(Fruit a) {
  switch(1.$SwitchMap$com$dengchengchao$Fruit[a.ordinal()]) {
  case 1:
   System.out.println("Orange");
   break;
  case 2:
   System.out.println("Apple");
   break;
  default:
   System.out.println("Banana");
  }
 }

可以看到,枚舉支持switch更加簡單,直接通過枚舉的順序即可作為相關(guān)case

總之:

switch的設(shè)計按道理來說,是比if-else要快的,但是在99.99%的情況下,他們性能差不多,除非case分支量巨大,但是在case分支過多的情況下,一般應(yīng)該考慮使用多態(tài)重構(gòu)了。

switch雖然支持byte,int,short,char,enum,String但是本質(zhì)上都是int,其他的只是編譯器幫你進行了語法糖優(yōu)化而已。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值

    如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值

    這篇文章主要介紹了如何在攔截器中獲取url路徑里面@PathVariable的參數(shù)值,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Mybatis基于xml配置實現(xiàn)單表的增刪改查功能

    Mybatis基于xml配置實現(xiàn)單表的增刪改查功能

    這篇文章主要介紹了Mybatis基于xml配置實現(xiàn)單表的增刪改查,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • Java多線程 原子操作類詳細

    Java多線程 原子操作類詳細

    這篇文章主要介紹了Java多線程中的原子操作類,原子的本意是不能被分割的粒子,而對于一個操作來說,如果它是不可被中斷的一個或者一組操作,那么他就是原子操作。顯然,原子操作是安全的,因為它不會被打斷,需要的朋友可以參考下
    2021-10-10
  • Java Socket編程(四) 重復(fù)和并發(fā)服務(wù)器

    Java Socket編程(四) 重復(fù)和并發(fā)服務(wù)器

    Java Socket編程(四) 重復(fù)和并發(fā)服務(wù)器...
    2006-12-12
  • springboot連接redis并動態(tài)切換database的實現(xiàn)方法

    springboot連接redis并動態(tài)切換database的實現(xiàn)方法

    這篇文章主要介紹了springboot連接redis并動態(tài)切換database,本文主為通過修改ConnectionFactory從而達到動態(tài)切換database的效果,結(jié)合示例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2022-03-03
  • SpringCache使用案例詳解

    SpringCache使用案例詳解

    這篇文章主要介紹了SpringCache使用案例詳解,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2023-11-11
  • maven?repository詳解

    maven?repository詳解

    這篇文章主要介紹了maven?repository的相關(guān)知識,本文通過示例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-05-05
  • JAVA實現(xiàn)將磁盤中所有空文件夾進行刪除的代碼

    JAVA實現(xiàn)將磁盤中所有空文件夾進行刪除的代碼

    這篇文章主要介紹了JAVA實現(xiàn)將磁盤中所有空文件夾進行刪除的代碼,需要的朋友可以參考下
    2017-06-06
  • JavaSE經(jīng)典小練習(xí)項目之拷貝文件夾

    JavaSE經(jīng)典小練習(xí)項目之拷貝文件夾

    文件拷貝是一個常見的任務(wù),無論是備份文件,還是將文件從一個位置復(fù)制到另一個位置,文件拷貝都是必不可少的,這篇文章主要給大家介紹了關(guān)于JavaSE經(jīng)典小練習(xí)項目之拷貝文件夾的相關(guān)資料,需要的朋友可以參考下
    2023-10-10
  • Java序列化常見的三個問題

    Java序列化常見的三個問題

    這篇文章主要介紹了Java序列化常見的三個問題,幫助大家更好的理解和學(xué)習(xí)JAVA,感興趣的朋友可以了解下
    2020-08-08

最新評論

略阳县| 连城县| 平潭县| 清远市| 平山县| 山阳县| 杭锦旗| 石狮市| 墨江| 凌海市| 化州市| 波密县| 秭归县| 扶绥县| 大邑县| 右玉县| 汉源县| 萝北县| 宁武县| 沐川县| 综艺| 柳州市| 竹北市| 天柱县| 六枝特区| 黎川县| 通化县| 伽师县| 眉山市| 伊宁市| 乌拉特前旗| 通海县| 遵化市| 逊克县| 枝江市| 黔江区| 桑日县| 平凉市| 南开区| 安吉县| 祁门县|