为什么 switch 里的 case 没有 break 不行
*明明只匹配了 case 0,为什么 1 和 2 也执行了??很费解!按照惯用套路,看看字节码能不能给个答案。
_javac_编译和_javap_查看:
[https://www.jianshu.com/p/85c55be35cdd](()
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 后代码也无法执行。那怎么办嘞....
![](https://img-blog.csdnimg.cn/20210617133452366. Java 开源项目【ali1024.coding.net/public/P7/Java/git】 gif#pic_center)
关于 goto
goto:无条件跳转,goto 1 表示跳转到标号 1 的代码处。
再写代码样例,这次在代码中给每个 case 都加上 break。
public static void main(String[] args) {
int i = 0;
switch (i) {
case 0:
System.out.println(0);
break;
case 10:
System.out.println(1);
break;
case 2:
System.out.println(2);
break;
}
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 被编译器视为无用代 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》开源 码进行了消除。
switch 和 if 区别
技术学习总结
学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。
最后面试分享
大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!
评论