欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

Switch語(yǔ)法

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

要什么switch,我有if-else

確實(shí),項(xiàng)目中使用switch比較少的一個(gè)主要原因就在于它的作用能被if-else代替,況且switch對(duì)類(lèi)型的限制,也阻礙了switch的進(jìn)一步使用。

先看看switch的語(yǔ)法:

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

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

為什么要有這些限制?

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

答案是:switch和if-else在設(shè)計(jì)的時(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是通過(guò)lookupswitch指令實(shí)現(xiàn)。那么lookupswitch指令是干嘛的呢?

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

switch可以被編譯為兩種指令

  • lookupswitch:當(dāng)switch的case比較稀疏的時(shí)候,使用該指令對(duì)int值的case進(jìn)行一一比較,直至找到對(duì)應(yīng)的case(這里的查找,可以?xún)?yōu)化為二分查找)
  • tableswitch:當(dāng)switch的case比較密集的時(shí)候,使用case的值作為switch的下標(biāo),可以在時(shí)間復(fù)雜度為O(1)的情況下找到對(duì)應(yīng)的case(可以類(lèi)比HashMap)

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

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

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

int之外的類(lèi)型

我們明白了byte,shor,char,int能被作為switch類(lèi)型后,再看看枚舉和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進(jìn)行反編譯得到如下代碼:

 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");
  }
 }

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

為了防止hash碰撞,代碼更加保險(xiǎn)的進(jìn)行了equals判斷。

再來(lái)看看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進(jìn)行反編譯得到如下代碼:

 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更加簡(jiǎn)單,直接通過(guò)枚舉的順序即可作為相關(guān)case

總之:

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

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

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

相關(guān)文章

  • 詳解spring boot配置 ssl

    詳解spring boot配置 ssl

    本篇文章主要介紹了詳解spring boot配置 ssl,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • java獲取包下被指定注解的類(lèi)過(guò)程解析

    java獲取包下被指定注解的類(lèi)過(guò)程解析

    這篇文章主要介紹了java獲取包下被指定注解的類(lèi)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot瘦身打包部署的實(shí)現(xiàn)

    SpringBoot瘦身打包部署的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot瘦身打包部署的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • 解決Nacos在執(zhí)行startup.cmd的時(shí)候出現(xiàn)閃退的問(wèn)題

    解決Nacos在執(zhí)行startup.cmd的時(shí)候出現(xiàn)閃退的問(wèn)題

    因?yàn)樵诠ぷ髦械捻?xiàng)目中需要使用到nacos作為注冊(cè)中心,但是在使用nacos的過(guò)程中運(yùn)行startup.cmd的時(shí)候出現(xiàn)了閃退的情況,運(yùn)行startup.cmd閃一下就沒(méi)有了,我把解決這個(gè)問(wèn)題的全過(guò)程理了一下,希望能幫到您,需要的朋友可以參考下
    2023-12-12
  • 基于SSM+Shiro+Bootstrap實(shí)現(xiàn)用戶(hù)權(quán)限管理系統(tǒng)

    基于SSM+Shiro+Bootstrap實(shí)現(xiàn)用戶(hù)權(quán)限管理系統(tǒng)

    這篇文章主要介紹了基于SSM+Shiro實(shí)現(xiàn)一個(gè)用戶(hù)權(quán)限管理系統(tǒng),每位用戶(hù)只可訪(fǎng)問(wèn)指定的頁(yè)面,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)或工作有一定幫助,快跟隨小編一起學(xué)習(xí)吧
    2021-12-12
  • java內(nèi)部類(lèi)的那些事兒_讓你一看就弄明白

    java內(nèi)部類(lèi)的那些事兒_讓你一看就弄明白

    本篇文章介紹了,java內(nèi)部類(lèi)的那些事兒。需要的朋友參考下
    2013-05-05
  • RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟

    這篇文章主要介紹了RabbitMQ的安裝和配置可視化界面的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-06-06
  • Springboot返回的json屏蔽某些屬性的操作

    Springboot返回的json屏蔽某些屬性的操作

    這篇文章主要介紹了Springboot返回的json屏蔽某些屬性的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-02-02
  • Java將集合List轉(zhuǎn)換成String字符串(或String轉(zhuǎn)換成List)詳解

    Java將集合List轉(zhuǎn)換成String字符串(或String轉(zhuǎn)換成List)詳解

    今天在寫(xiě)項(xiàng)目的時(shí)候遇到一個(gè)問(wèn)題,就是要把得到的一個(gè)集合轉(zhuǎn)換成字符串,下面這篇文章主要給大家介紹了關(guān)于Java將集合List轉(zhuǎn)換成String字符串(或String轉(zhuǎn)換成List)的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • java設(shè)計(jì)模式—靜態(tài)代理模式(聚合與繼承方式對(duì)比)

    java設(shè)計(jì)模式—靜態(tài)代理模式(聚合與繼承方式對(duì)比)

    下面小編就為大家?guī)?lái)一篇java設(shè)計(jì)模式—靜態(tài)代理模式(聚合與繼承方式對(duì)比)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05

最新評(píng)論