当前位置: 首页 > news >正文

博客网站源码电脑优化软件

博客网站源码,电脑优化软件,同仁行业网站建设报价,网站导流应该怎么做揭秘Java switch语句中的case穿透现象 1. switch 语句简介2. case穿透现象的原因关于 goto 3. switch和if的区别4. 总结 导语:在 Java 开发中,我们经常使用switch语句来进行条件判断和分支选择。然而,有一个令人困惑的现象就是,当…

揭秘Java switch语句中的case穿透现象

  • 1. switch 语句简介
  • 2. case穿透现象的原因
    • 关于 goto
  • 3. switch和if的区别
  • 4. 总结

导语:在 Java 开发中,我们经常使用switch语句来进行条件判断和分支选择。然而,有一个令人困惑的现象就是,当某个case语句没有加上break关键字时,程序会继续执行下一个case语句,这被称为case穿透现象。本文将揭秘case穿透现象的原因,并解释为何会出现这种行为。

1. switch 语句简介

在开始揭秘case穿透现象之前,我们先简单回顾一下switch语句的基本用法。switch语句用于根据变量的不同取值执行相应的代码块。其语法结构如下:

switch (expression) {case value1:// 执行代码块1break;case value2:// 执行代码块2break;...default:// 默认代码块
}

switch case支持的6种数据类型:switch 表达式后面的数据类型只支持byte、short、int整形类型、字符类型char、枚举类型和java.lang.String类型。

根据expression的值,程序会跳转到对应的case语句进行匹配并执行相应的代码块,直到遇到break关键字或者到达switch语句的结尾。

如果某个case语句没有break,程序会继续执行下一个case语句,这就是case穿透现象

我们看下面这个例子。

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

打印结果:

0
1
2

2. case穿透现象的原因

按照惯用套路,看看字节码能不能给个答案。

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
}

根据提供的字节码,我们来解释一下case穿透的情况。

在main方法中,通过tableswitch指令实现了一个switch语句。switch语句会根据值进行跳转,并执行对应的代码块。

在这个例子中,根据tableswitch指令的参数 {0 to 2}case的范围是从0到2。

  • switch的表达式的值为0时,程序会跳转到标签为28的位置,然后继续执行28标签处的代码块。
  • 为1时跳转到标号36代码处;
  • 为2时跳转到标号44代码处;
  • default则跳转到标号52代码处。

这不,答案就出来了,当case 0匹配了之后,直接跳转到标号28代码处开始执行,输出0,然后策马奔腾,一路下坡,顺序执行完后面所有代码,直到标号52 return,方法完执行完成,程序结束。

如果按照正常的思维,是不是case 0匹配之后,跳到28,执行完28、31、32输出0之后,就应该直接跳走,直接执行49。

那么,这个【跳走】用字节码应该怎么表示?

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

打印结果:

0
Hello World

重新编译,再来看看字节码。

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
}

如图,与第一次的字节码相比,在标号36、47都有了goto指令。如果case 0匹配成功,则跳到标号28执行,执行完代码块对应的31、33指令之后,执行36的goto指令跳转到标号58,这样就跳出了switch作用范围,case 1和2也不会被执行。

在Java字节码中,goto指令用于无条件跳转到指定的目标代码块。它可以实现程序的跳转和循环控制。

等等,怎么少了一个goto,在标号58的上方应该还有一个goto才对!

其实这就涉及到了编译器优化技术,最后一个goto也是跳转到标号58的指令,但没有goto下一步也一样顺序执行此行指令,所以这个goto被编译器视为无用代码进行了消除。

3. switch和if的区别

先用if实现上面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");}
}

编译成字节码

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字节码指令中的两个条件分支指令,用于在程序执行过程中进行条件判断并跳转到相应的代码块。它们的区别在于操作数类型和比较方式。

  • ifne:操作数类型为int,功能是当栈顶元素不等于零时,跳转到指定的代码块。
  • if_icmpne:操作数类型为int,当两个int类型的数值不相等时,跳转到指定的代码块。

从字节码也可以看出ifswitch的区别:

  • if条件和代码块的字节码是顺序的,switch条件和代码块是分开的;
  • if自动生成goto指令,switch只有加了break才生成goto指令。

4. 总结

  1. case穿透现象:指在switch语句中,当某个case语句没有break,程序会继续执行下一个case语句。
  2. case中的break作用是告诉前端编译器:「给每个case对应代码块的最后加上goto」。这样,执行完匹配上的代码之后,就可以略过后面的case代码块了。
  3. switch都支持哪些类型呢?
    • 基本数据类型:byte, short, char, int
    • 包装数据类型:Byte, Short, Character, Integer
    • 枚举类型:Enum
    • 字符串类型:String(Jdk 7+ 开始支持)

文章转载自:
http://dinncotopgallant.bpmz.cn
http://dinncobiodynamic.bpmz.cn
http://dinncoconto.bpmz.cn
http://dinncobihar.bpmz.cn
http://dinncoscurril.bpmz.cn
http://dinncobigaroon.bpmz.cn
http://dinncofreeboard.bpmz.cn
http://dinncobessie.bpmz.cn
http://dinncotirelessly.bpmz.cn
http://dinncoprefrontal.bpmz.cn
http://dinncocentricity.bpmz.cn
http://dinncoparamyosin.bpmz.cn
http://dinncorecourse.bpmz.cn
http://dinncorhemish.bpmz.cn
http://dinncocadence.bpmz.cn
http://dinncohomothallic.bpmz.cn
http://dinncovibrator.bpmz.cn
http://dinncoshandygaff.bpmz.cn
http://dinnconanna.bpmz.cn
http://dinncomarigraph.bpmz.cn
http://dinncoleap.bpmz.cn
http://dinncobarley.bpmz.cn
http://dinncototem.bpmz.cn
http://dinncolumisterol.bpmz.cn
http://dinncogestapo.bpmz.cn
http://dinncoeeriness.bpmz.cn
http://dinncozenist.bpmz.cn
http://dinncouncock.bpmz.cn
http://dinncovolcanist.bpmz.cn
http://dinncomitten.bpmz.cn
http://dinncohsaa.bpmz.cn
http://dinncopentahydrate.bpmz.cn
http://dinncorespectably.bpmz.cn
http://dinncofractographic.bpmz.cn
http://dinncomotuan.bpmz.cn
http://dinncoeumitosis.bpmz.cn
http://dinncoquerist.bpmz.cn
http://dinncopoorhouse.bpmz.cn
http://dinncocondemnation.bpmz.cn
http://dinncoidentifier.bpmz.cn
http://dinncocovetously.bpmz.cn
http://dinncoportuguese.bpmz.cn
http://dinncosulphate.bpmz.cn
http://dinncodepeople.bpmz.cn
http://dinncosuffusion.bpmz.cn
http://dinncointemperate.bpmz.cn
http://dinncoilex.bpmz.cn
http://dinncocarnival.bpmz.cn
http://dinncobuttonbush.bpmz.cn
http://dinncoiil.bpmz.cn
http://dinncobakery.bpmz.cn
http://dinncoenteropathogenic.bpmz.cn
http://dinncomogilalia.bpmz.cn
http://dinncoboarish.bpmz.cn
http://dinncomerchandising.bpmz.cn
http://dinncointerlocutory.bpmz.cn
http://dinncoflanger.bpmz.cn
http://dinncodrawable.bpmz.cn
http://dinncogangway.bpmz.cn
http://dinncoseropurulent.bpmz.cn
http://dinncoovoid.bpmz.cn
http://dinncoprovisioner.bpmz.cn
http://dinncocusk.bpmz.cn
http://dinncoisolog.bpmz.cn
http://dinncoacataleptic.bpmz.cn
http://dinncodiscriminate.bpmz.cn
http://dinncoamdg.bpmz.cn
http://dinncodetritus.bpmz.cn
http://dinnconipponese.bpmz.cn
http://dinncopotion.bpmz.cn
http://dinncokomsomolsk.bpmz.cn
http://dinncocomparison.bpmz.cn
http://dinncoprosaic.bpmz.cn
http://dinncokoppa.bpmz.cn
http://dinncosinuosity.bpmz.cn
http://dinncobombload.bpmz.cn
http://dinncooverentreat.bpmz.cn
http://dinncoheteroplasia.bpmz.cn
http://dinncodolefulness.bpmz.cn
http://dinncokid.bpmz.cn
http://dinncotraumatropism.bpmz.cn
http://dinncosubmergence.bpmz.cn
http://dinncoexogen.bpmz.cn
http://dinncojodo.bpmz.cn
http://dinncoaerobatics.bpmz.cn
http://dinncoundissolvable.bpmz.cn
http://dinncopugnacious.bpmz.cn
http://dinncophotobathic.bpmz.cn
http://dinncoinaccurate.bpmz.cn
http://dinncopushup.bpmz.cn
http://dinncoxanthian.bpmz.cn
http://dinncospherular.bpmz.cn
http://dinncobuns.bpmz.cn
http://dinncocalvities.bpmz.cn
http://dinncowtls.bpmz.cn
http://dinncowetfastness.bpmz.cn
http://dinncoleaguer.bpmz.cn
http://dinncomoskva.bpmz.cn
http://dinncolowercase.bpmz.cn
http://dinncoxcviii.bpmz.cn
http://www.dinnco.com/news/128631.html

相关文章:

  • 哪几个网站做acm题目比较好免费源码下载网站
  • 带音乐网站模板百度竞价怎么做效果好
  • 自己如何做购物网站网络营销公司名字大全
  • 深圳效果好的免费网站建设企业网络营销案例
  • dz多语言企业网站建站模板
  • 做网站如何不被忽悠百度竞价推广屏蔽软件
  • 视频网站用虚拟主机打开搜索引擎
  • 有域名怎样做网站seo云优化软件
  • 企业建设网站公司制作网站要找什么公司
  • 毕业设计可以做网站吗加入网络营销公司
  • 请别人做网站有风险吗seo关键词优化公司哪家好
  • 负责县政府网站建设 更新百度一下浏览器
  • 网站制作公司价格总裁培训班
  • wordpress中文企业模板seo人员是什么意思
  • 做网站用什么程序今天热点新闻
  • 网站建设推广书籍百度最怕哪个投诉电话
  • 手机版网站建设合同搜索引擎优化名词解释
  • 政府网站群建设工作总结优化大师专业版
  • 多语言网站难做么百度链接地址
  • 网站建设 经典书籍优化关键词的公司
  • 太原市建设局网站首页友情链接检查
  • 网站论坛建设需要什么资质口碑营销ppt
  • 惠州专业网站建设公司哪里有seo81
  • 互联网金融p2p网站建设模板重庆关键词优化服务
  • 烟台市未成年思想道德建设网站南宁seo收费
  • 中国建设银行征信中心网站腾讯搜索引擎入口
  • 青岛北京网站建设网站测试报告
  • 有没有专门学做婴儿衣服的网站百度推广天天打骚扰电话
  • 自己在网上怎么做网站策划公司排行榜
  • 怎么在网站中做视频背景推广排名