国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

啤酒免費代理0元鋪貨優(yōu)化軟件有哪些

啤酒免費代理0元鋪貨,優(yōu)化軟件有哪些,wordpress隱藏目錄路徑,電子商務(wù)網(wǎng)站建設(shè)php揭秘Java switch語句中的case穿透現(xiàn)象 1. switch 語句簡介2. case穿透現(xiàn)象的原因關(guān)于 goto 3. switch和if的區(qū)別4. 總結(jié) 導(dǎo)語:在 Java 開發(fā)中,我們經(jīng)常使用switch語句來進(jìn)行條件判斷和分支選擇。然而,有一個令人困惑的現(xiàn)象就是,當(dāng)…

揭秘Java switch語句中的case穿透現(xiàn)象

  • 1. switch 語句簡介
  • 2. case穿透現(xiàn)象的原因
    • 關(guān)于 goto
  • 3. switch和if的區(qū)別
  • 4. 總結(jié)

導(dǎo)語:在 Java 開發(fā)中,我們經(jīng)常使用switch語句來進(jìn)行條件判斷和分支選擇。然而,有一個令人困惑的現(xiàn)象就是,當(dāng)某個case語句沒有加上break關(guān)鍵字時,程序會繼續(xù)執(zhí)行下一個case語句,這被稱為case穿透現(xiàn)象。本文將揭秘case穿透現(xiàn)象的原因,并解釋為何會出現(xiàn)這種行為。

1. switch 語句簡介

在開始揭秘case穿透現(xiàn)象之前,我們先簡單回顧一下switch語句的基本用法。switch語句用于根據(jù)變量的不同取值執(zhí)行相應(yīng)的代碼塊。其語法結(jié)構(gòu)如下:

switch (expression) {case value1:// 執(zhí)行代碼塊1break;case value2:// 執(zhí)行代碼塊2break;...default:// 默認(rèn)代碼塊
}

switch case支持的6種數(shù)據(jù)類型:switch 表達(dá)式后面的數(shù)據(jù)類型只支持byte、short、int整形類型、字符類型char、枚舉類型和java.lang.String類型。

根據(jù)expression的值,程序會跳轉(zhuǎn)到對應(yīng)的case語句進(jìn)行匹配并執(zhí)行相應(yīng)的代碼塊,直到遇到break關(guān)鍵字或者到達(dá)switch語句的結(jié)尾。

如果某個case語句沒有break,程序會繼續(xù)執(zhí)行下一個case語句,這就是case穿透現(xiàn)象。

我們看下面這個例子。

public class Test {public static void main(String[] args) {int i = 0;switch (i) {case 0:System.out.println("0");case 1:System.out.println("1");case 2:System.out.println("2");}}
}

打印結(jié)果:

0
1
2

2. case穿透現(xiàn)象的原因

按照慣用套路,看看字節(jié)碼能不能給個答案。

javac編譯javap查看

> javap -c -l Test.class
Compiled from "Test.java"
public class com.atu.algorithm.aTest.Test {public com.atu.algorithm.aTest.Test();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 8: 0public static void main(java.lang.String[]);Code:0: iconst_01: istore_12: iload_13: tableswitch   { // 0 to 20: 281: 362: 44default: 52}28: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;31: ldc           #3                  // String 033: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V36: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;39: ldc           #5                  // String 141: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V44: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;47: ldc           #6                  // String 249: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V52: returnLineNumberTable:line 10: 0line 11: 2line 13: 28line 15: 36line 17: 44line 19: 52
}

根據(jù)提供的字節(jié)碼,我們來解釋一下case穿透的情況。

在main方法中,通過tableswitch指令實現(xiàn)了一個switch語句。switch語句會根據(jù)值進(jìn)行跳轉(zhuǎn),并執(zhí)行對應(yīng)的代碼塊。

在這個例子中,根據(jù)tableswitch指令的參數(shù) {0 to 2}case的范圍是從0到2。

  • 當(dāng)switch的表達(dá)式的值為0時,程序會跳轉(zhuǎn)到標(biāo)簽為28的位置,然后繼續(xù)執(zhí)行28標(biāo)簽處的代碼塊。
  • 為1時跳轉(zhuǎn)到標(biāo)號36代碼處;
  • 為2時跳轉(zhuǎn)到標(biāo)號44代碼處;
  • default則跳轉(zhuǎn)到標(biāo)號52代碼處。

這不,答案就出來了,當(dāng)case 0匹配了之后,直接跳轉(zhuǎn)到標(biāo)號28代碼處開始執(zhí)行,輸出0,然后策馬奔騰,一路下坡,順序執(zhí)行完后面所有代碼,直到標(biāo)號52 return,方法完執(zhí)行完成,程序結(jié)束。

如果按照正常的思維,是不是case 0匹配之后,跳到28,執(zhí)行完28、31、32輸出0之后,就應(yīng)該直接跳走,直接執(zhí)行49。

那么,這個【跳走】用字節(jié)碼應(yīng)該怎么表示?

關(guān)于 goto

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

public class Test {public static void main(String[] args) {int i = 0;switch (i) {case 0:System.out.println("0");break;case 1:System.out.println("1");break;case 2:System.out.println("2");break;}System.out.println("Hello World");}
}

打印結(jié)果:

0
Hello World

重新編譯,再來看看字節(jié)碼。

Compiled from "Test.java"
public class com.atu.algorithm.aTest.Test {public com.atu.algorithm.aTest.Test();   Code:                                  0: aload_0                                                                  1: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 8: 0public static void main(java.lang.String[]);Code:0: iconst_01: istore_12: iload_13: tableswitch   { // 0 to 20: 281: 392: 50default: 58}28: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;31: ldc           #3                  // String 033: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V36: goto          5839: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;42: ldc           #5                  // String 144: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V47: goto          5850: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;53: ldc           #6                  // String 255: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V58: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;61: ldc           #7                  // String Hello World63: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V66: returnLineNumberTable:line 10: 0line 11: 2line 13: 28line 14: 36line 16: 39line 17: 47line 19: 50line 22: 58line 23: 66
}

如圖,與第一次的字節(jié)碼相比,在標(biāo)號36、47都有了goto指令。如果case 0匹配成功,則跳到標(biāo)號28執(zhí)行,執(zhí)行完代碼塊對應(yīng)的31、33指令之后,執(zhí)行36的goto指令跳轉(zhuǎn)到標(biāo)號58,這樣就跳出了switch作用范圍,case 1和2也不會被執(zhí)行。

在Java字節(jié)碼中,goto指令用于無條件跳轉(zhuǎn)到指定的目標(biāo)代碼塊。它可以實現(xiàn)程序的跳轉(zhuǎn)和循環(huán)控制。

等等,怎么少了一個goto,在標(biāo)號58的上方應(yīng)該還有一個goto才對!

其實這就涉及到了編譯器優(yōu)化技術(shù),最后一個goto也是跳轉(zhuǎn)到標(biāo)號58的指令,但沒有g(shù)oto下一步也一樣順序執(zhí)行此行指令,所以這個goto被編譯器視為無用代碼進(jìn)行了消除。

3. switch和if的區(qū)別

先用if實現(xiàn)上面switch邏輯。

public class Test {public static void main(String[] args) {int i = 0;if (i == 0) {System.out.println(0);} else if (i == 1) {System.out.println(1);} else if (i == 2) {System.out.println(2);}System.out.println("Hello World");}
}

編譯成字節(jié)碼

Compiled from "Test.java"
public class com.atu.algorithm.aTest.Test {public com.atu.algorithm.aTest.Test();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 8: 0public static void main(java.lang.String[]);Code:0: iconst_01: istore_12: iload_13: ifne          166: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;9: iconst_010: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V13: goto          4316: iload_117: iconst_118: if_icmpne     3121: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;24: iconst_125: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V28: goto          4331: iload_132: iconst_233: if_icmpne     4336: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;39: iconst_240: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V43: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;46: ldc           #4                  // String Hello World48: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V51: return
}

「ifne」和「if_icmpne」是Java字節(jié)碼指令中的兩個條件分支指令,用于在程序執(zhí)行過程中進(jìn)行條件判斷并跳轉(zhuǎn)到相應(yīng)的代碼塊。它們的區(qū)別在于操作數(shù)類型和比較方式。

  • ifne:操作數(shù)類型為int,功能是當(dāng)棧頂元素不等于零時,跳轉(zhuǎn)到指定的代碼塊。
  • if_icmpne:操作數(shù)類型為int,當(dāng)兩個int類型的數(shù)值不相等時,跳轉(zhuǎn)到指定的代碼塊。

從字節(jié)碼也可以看出ifswitch的區(qū)別:

  • if條件和代碼塊的字節(jié)碼是順序的,switch條件和代碼塊是分開的;
  • if自動生成goto指令,switch只有加了break才生成goto指令。

4. 總結(jié)

  1. case穿透現(xiàn)象:指在switch語句中,當(dāng)某個case語句沒有break,程序會繼續(xù)執(zhí)行下一個case語句。
  2. case中的break作用是告訴前端編譯器:「給每個case對應(yīng)代碼塊的最后加上goto」。這樣,執(zhí)行完匹配上的代碼之后,就可以略過后面的case代碼塊了。
  3. switch都支持哪些類型呢?
    • 基本數(shù)據(jù)類型:byte, short, char, int
    • 包裝數(shù)據(jù)類型:Byte, Short, Character, Integer
    • 枚舉類型:Enum
    • 字符串類型:String(Jdk 7+ 開始支持)
http://aloenet.com.cn/news/31040.html

相關(guān)文章:

  • 網(wǎng)站策劃包括什么國內(nèi)免費b2b網(wǎng)站大全
  • 網(wǎng)站建設(shè)死人接單關(guān)鍵詞查找工具
  • 網(wǎng)站做xss過濾seo快速排名軟件平臺
  • 做網(wǎng)站很累官方網(wǎng)站怎么注冊
  • wordpress搭建影視站百度引擎提交入口
  • 揚州廣陵區(qū)城鄉(xiāng)建設(shè)局網(wǎng)站怎么快速刷排名
  • 做網(wǎng)站必須有云虛擬主機(jī)上海app定制開發(fā)公司
  • 濟(jì)南做網(wǎng)站互聯(lián)網(wǎng)公司有哪些百度搜索網(wǎng)址大全
  • 沈陽網(wǎng)站制作定制廠家站內(nèi)營銷推廣方式
  • 網(wǎng)站基礎(chǔ)知識域名5個點突發(fā)大事震驚全國
  • 35互聯(lián)做的網(wǎng)站房產(chǎn)網(wǎng)站建設(shè)
  • 做淘寶保健品藥品在哪個網(wǎng)站找素材想做推廣哪個平臺好
  • 合肥哪個公司做網(wǎng)站好廣告推廣怎么做最有效
  • 豬八戒做網(wǎng)站靠譜嗎seo建站
  • 短期網(wǎng)站建設(shè)培訓(xùn)百度sem是什么意思
  • 彩妝網(wǎng)站建設(shè)標(biāo)題優(yōu)化怎樣選關(guān)鍵詞
  • 基于jsp的精品課程網(wǎng)站建設(shè)泉州關(guān)鍵詞優(yōu)化排名
  • 本地怎樣上傳自己做的網(wǎng)站seo優(yōu)化價格
  • 沭陽做網(wǎng)站營銷比較好的知名公司有哪些
  • 城鄉(xiāng)建設(shè)網(wǎng)站證件查詢谷歌外貿(mào)seo
  • 門戶網(wǎng)站簡介合肥百度快速排名提升
  • 佳木斯企業(yè)網(wǎng)站建設(shè)專業(yè)軟文發(fā)稿平臺
  • 動漫設(shè)計和動畫設(shè)計單詞優(yōu)化和整站優(yōu)化
  • 建設(shè)網(wǎng)站建設(shè)投標(biāo)網(wǎng)1249中官網(wǎng)詞建網(wǎng)站教學(xué)
  • 藥房網(wǎng)站模板網(wǎng)絡(luò)推廣方法的分類
  • 沈陽做網(wǎng)站推廣網(wǎng)站關(guān)鍵詞推廣優(yōu)化
  • 深圳o2o網(wǎng)站建設(shè)沈陽seo關(guān)鍵詞
  • 廣州網(wǎng)站改版 網(wǎng)站建設(shè)網(wǎng)站頁面禁止訪問
  • 移動端網(wǎng)站建設(shè)的方案用asp做的網(wǎng)站
  • 如何在網(wǎng)站后臺做網(wǎng)頁代運營公司