成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

為什么switch里的case沒有break不行

開發 后端
之所以這么篤定地回答這個問題,并不是我知道其中原理,而是之前在一個群里,有人問了同類型的問題,我瞥了一眼記住了答案,所以才依葫蘆畫瓢。

[[412376]]

 前言

一個小姐姐拿著一個switch的選擇題來問我。

之所以這么篤定地回答這個問題,并不是我知道其中原理,而是之前在一個群里,有人問了同類型的問題,我瞥了一眼記住了答案,所以才依葫蘆畫瓢。

小姐姐接著問我為什么,我說少個break,但凡再問一句:為什么少個break結果就不一樣,我就回答不出來了。所以,為了將尷尬扼殺于搖籃,還是研究一下break在switch的作用。

 從字節碼出發

按照慣例,先寫demo表述問題。 

  1. public static void main(String[] args) {  
  2.    int i = 0 
  3.    switch (i) {  
  4.        case 0:  
  5.            System.out.println(0);  
  6.        case 1:  
  7.            System.out.println(1);  
  8.        case 2:  
  9.            System.out.println(2);  
  10.  } 

運行代碼,結果如下:

*明明只匹配了case 0,為什么1和2也執行了? 很費解!按照慣用套路,看看字節碼能不能給個答案。

javac編譯和javap查看:

「tableswitch」和「lookupswitch」都用于switch條件跳轉,前者用于case值連續,例如上面代碼中的0、1、2;后者用于case值不連續。

從字節碼可以看出:switch中的case條件和對應代碼塊是分開的。如上圖,case為0時,跳轉到標號28代碼處;為1時跳轉到標號35代碼處;為2時跳轉到標號43代碼處;default則跳轉到標號49代碼處。

這不,答案就出來了,當case 0匹配了之后,直接跳轉到標號28代碼處開始執行,輸出0,然后策馬奔騰,一路小下坡,順序執行完后面所有代碼,直到標號49 return,方法完執行完成,程序結束。

如果按照正常的思維,是不是case 0匹配之后,跳到28,執行完28、31、32輸出0之后,就應該直接跳走,直接執行49。那么,這個"跳走”用字節碼應該怎么表示?

用return?那不行,因為return會結束方法,這樣switch后代碼也無法執行。那怎么辦嘞.... 

關于goto

goto:無條件跳轉,goto 1表示跳轉到標號1的代碼處。

再寫代碼樣例,這次在代碼中給每個case都加上break。 

  1. public static void main(String[] args) {  
  2.     int i = 0 
  3.     switch (i) {  
  4.         case 0:  
  5.             System.out.println(0);  
  6.             break;  
  7.         case 10:  
  8.             System.out.println(1);  
  9.             break;  
  10.         case 2:  
  11.             System.out.println(2);  
  12.             break;  
  13.     }  
  14.     System.out.println("Hello World");  

重新編譯,再來看看字節碼。

如圖,與第一次的字節碼相比,在標號35、45都有了goto指令。如果case 0匹配成功,則跳到標號28執行,執行完代碼塊對應的31、32指令之后,執行35的goto指令跳轉到標號55,這樣就跳出了switch作用范圍,case 1和2也不會被執行。

等等,怎么少了一個goto,在標號55的上方應該還有一個goto才對!其實這就涉及到了編譯器優化技術,最后一個goto也是跳轉到標號55的指令,但沒有goto下一步也一樣順序執行此行指令,所以這個goto被編譯器視為無用代碼進行了消除。 

switch和if區別

先用if實現上面switch邏輯。 

  1. public static void main(String[] args) {  
  2.     int i = 0 
  3.     if (i == 0) {  
  4.         System.out.println(0);  
  5.     } else if (i == 1) {  
  6.         System.out.println(1);  
  7.     } else if (i == 2) {  
  8.         System.out.println(2);  
  9.     }  

編譯成字節碼:

「if_icmpne」用于比較兩個int數。從字節碼也可以看出if和switch的區別:if條件和代碼塊的字節碼是順序的,switch條件和代碼塊是分開的;if自動生成goto指令,switch只有加了break才生成goto指令。 

結語

case中的break告訴前端編譯器:「給每個case對應代碼塊的最后加上goto」。這樣,執行完匹配上的代碼之后,就可以略過后面的case代碼塊了。

果然,求(xiao)知(jie)欲(jie)才是學習新知識的動力。 

 

責任編輯:龐桂玉 來源: Hollis
相關推薦

2020-07-16 15:20:13

switch...caif...else語言

2023-06-26 07:31:29

中文編程編碼

2021-04-05 14:47:05

裝飾器Python代碼

2013-01-22 09:35:27

Hadoop存儲

2009-06-08 21:45:46

Javaswitch-case

2009-08-19 10:41:14

C# switch和c

2021-05-08 08:55:54

CPUIBMIntel

2011-05-25 14:59:35

if elseswitch case

2017-01-13 23:06:45

swiftios

2020-10-09 06:48:19

Pythonswitch語句

2022-06-12 21:36:57

Hooksreact

2015-08-06 10:19:19

編程腦子

2011-07-21 11:11:10

Scrum

2021-04-20 19:23:07

語法switch-casePython

2019-08-15 16:48:30

2021-01-20 12:44:22

JAVA編程語言軟件

2021-01-20 12:43:07

編程語言Java

2020-07-22 07:55:12

Python開發函數

2010-02-02 17:20:44

C++ switch-

2022-12-07 09:00:18

錯誤異常CGO
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国内自拍第一页 | 99国产精品久久久 | 9191在线观看| 免费不卡一区 | 日韩av在线免费 | 97久久精品午夜一区二区 | 四虎影音 | 久久免费视频1 | 国产精品久久国产精品 | 欧美日韩不卡 | 欧美一级二级视频 | 国产欧美日韩一区 | 成人免费看电影 | 久久久精品网 | 亚洲精品一区在线观看 | 亚洲一区二区av在线 | 国产欧美日韩在线播放 | 伦理片97| 国产在线拍偷自揄拍视频 | 9999国产精品欧美久久久久久 | 日韩第一区 | 91在线视频观看免费 | 久久久久久久久久久91 | 精品国产免费一区二区三区演员表 | 91麻豆产精品久久久久久 | 久久久久久国产精品久久 | 久久精品无码一区二区三区 | www.精品国产 | 国产小视频在线看 | 最新91在线 | 日韩中文字幕免费在线观看 | 日韩在线一区二区三区 | 毛片a区| 欧美在线| 天堂中文资源在线 | 一区二区三区视频在线 | www.日本国产 | 日韩在线播放av | av网站在线看 | 欧美成ee人免费视频 | 日韩高清国产一区在线 |