中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

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

網(wǎng)站建設(shè)要考慮哪些企業(yè)如何進(jìn)行網(wǎng)絡(luò)營(yíng)銷

網(wǎng)站建設(shè)要考慮哪些,企業(yè)如何進(jìn)行網(wǎng)絡(luò)營(yíng)銷,知名app開發(fā)公司,怎么利用百度云盤做網(wǎng)站揭秘Java switch語句中的case穿透現(xiàn)象 1. switch 語句簡(jiǎn)介2. case穿透現(xiàn)象的原因關(guān)于 goto 3. switch和if的區(qū)別4. 總結(jié) 導(dǎo)語:在 Java 開發(fā)中,我們經(jīng)常使用switch語句來進(jìn)行條件判斷和分支選擇。然而,有一個(gè)令人困惑的現(xiàn)象就是,當(dāng)…

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

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

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

1. switch 語句簡(jiǎn)介

在開始揭秘case穿透現(xiàn)象之前,我們先簡(jiǎ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的值,程序會(huì)跳轉(zhuǎn)到對(duì)應(yīng)的case語句進(jìn)行匹配并執(zhí)行相應(yīng)的代碼塊,直到遇到break關(guān)鍵字或者到達(dá)switch語句的結(jié)尾。

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

我們看下面這個(gè)例子。

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é)碼能不能給個(gè)答案。

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指令實(shí)現(xiàn)了一個(gè)switch語句。switch語句會(huì)根據(jù)值進(jìn)行跳轉(zhuǎn),并執(zhí)行對(duì)應(yīng)的代碼塊。

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

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

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

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

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

關(guān)于 goto

再寫代碼樣例,這次我們?cè)诖a中給每個(gè)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)號(hào)36、47都有了goto指令。如果case 0匹配成功,則跳到標(biāo)號(hào)28執(zhí)行,執(zhí)行完代碼塊對(duì)應(yīng)的31、33指令之后,執(zhí)行36的goto指令跳轉(zhuǎn)到標(biāo)號(hào)58,這樣就跳出了switch作用范圍,case 1和2也不會(huì)被執(zhí)行。

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

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

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

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

先用if實(shí)現(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é)碼指令中的兩個(gè)條件分支指令,用于在程序執(zhí)行過程中進(jìn)行條件判斷并跳轉(zhuǎn)到相應(yīng)的代碼塊。它們的區(qū)別在于操作數(shù)類型和比較方式。

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

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

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

4. 總結(jié)

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

相關(guān)文章:

  • 做圖網(wǎng)站有哪些東西嗎建網(wǎng)站用什么軟件
  • 用java做視頻網(wǎng)站app投放渠道有哪些
  • django做的網(wǎng)站舉例資源網(wǎng)站優(yōu)化排名軟件
  • 跨越速運(yùn)在黑龍江黑河網(wǎng)點(diǎn)網(wǎng)絡(luò)優(yōu)化工程師主要做什么
  • 望牛墩做網(wǎng)站每日軍事新聞
  • 廣西中國(guó)建設(shè)銀行網(wǎng)站首頁百度網(wǎng)站收錄提交
  • 做網(wǎng)站指導(dǎo)seo流量工具
  • 菲律賓 做菠菜網(wǎng)站視頻外鏈在線生成
  • jquery 素材的網(wǎng)站seo基本概念
  • 長(zhǎng)沙專門做網(wǎng)站建設(shè)的公司2024年1月新冠高峰期
  • 企業(yè)網(wǎng)站建立流程百度站長(zhǎng)平臺(tái)鏈接
  • 2345電視劇網(wǎng)站免費(fèi)鄭州seo服務(wù)公司
  • sae wordpress 圖片北京網(wǎng)站優(yōu)化站優(yōu)化
  • 學(xué)做蛋糕網(wǎng)站如何讓自己網(wǎng)站排名提高
  • 針對(duì)網(wǎng)站做搜索引擎做優(yōu)化網(wǎng)盤資源共享網(wǎng)站
  • 微交易網(wǎng)站建設(shè)實(shí)時(shí)積分榜
  • 溫州龍灣做網(wǎng)站2022年最好用的搜索引擎
  • wordpress搜索產(chǎn)品偽靜態(tài)博客seo優(yōu)化技術(shù)
  • 政府門戶網(wǎng)站建設(shè)的意義電腦培訓(xùn)學(xué)校
  • 無錫知名網(wǎng)站制作百度網(wǎng)站打不開
  • 網(wǎng)站設(shè)計(jì)過程中需要注意的問題網(wǎng)站網(wǎng)頁的優(yōu)化方法
  • 網(wǎng)站開發(fā)的作用建站之星
  • 做論壇網(wǎng)站需要什么備案網(wǎng)站友鏈交換平臺(tái)
  • 做網(wǎng)站網(wǎng)絡(luò)營(yíng)銷策略有哪幾種
  • 福永網(wǎng)站設(shè)計(jì)多少錢seo入門免費(fèi)教程
  • 北京自助模板建站黑馬程序員培訓(xùn)機(jī)構(gòu)在哪
  • 學(xué)生做的網(wǎng)站成品網(wǎng)絡(luò)客服
  • 西安微網(wǎng)站制作網(wǎng)上廣告宣傳怎么做
  • 畢業(yè)設(shè)計(jì)網(wǎng)站成品百度接單平臺(tái)
  • 做B2C獨(dú)立網(wǎng)站的話需要做海外倉嗎人際網(wǎng)絡(luò)營(yíng)銷2900