写点什么

为什么 switch 里的 case 没有 break 不行

  • 2022 年 4 月 21 日
  • 本文字数:1057 字

    阅读完需:约 3 分钟

*明明只匹配了 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 区别



技术学习总结

学习技术一定要制定一个明确的学习路线,这样才能高效的学习,不必要做无效功,既浪费时间又得不到什么效率,大家不妨按照我这份路线来学习。




最后面试分享

大家不妨直接在牛客和力扣上多刷题,同时,我也拿了一些面试题跟大家分享,也是从一些大佬那里获得的,大家不妨多刷刷题,为金九银十冲一波!




用户头像

还未添加个人签名 2022.04.13 加入

还未添加个人简介

评论

发布
暂无评论
为什么switch里的case没有break不行_Java_爱好编程进阶_InfoQ写作社区