首页 > 其他分享 >什么swtich中case没有break不行?

什么swtich中case没有break不行?

时间:2022-12-07 16:02:07浏览次数:46  
标签:swtich case goto 代码 标号 break 跳转

前言

一个小姐姐拿着一个switch的选择题来问我。

之所以这么笃定地回答这个问题,并不是我知道其中原理,而是之前在一个群里,有人问了同类型的问题,我瞥了一眼记住了答案,所以才依葫芦画瓢。

小姐姐接着问我为什么,我说少个break,但凡再问一句:为什么少个break结果就不一样,我就回答不出来了。所以,为了将尴尬扼杀于摇篮,还是研究一下break在switch的作用。

从字节码出发

按照惯例,先写demo表述问题。

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

运行代码,结果如下:

*明明只匹配了case 0,为什么1和2也执行了? 很费解!按照惯用套路,看看字节码能不能给个答案。

javac编译和javap查看:

tableswitchlookupswitch都用于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后代码也无法执行。那怎么办嘞….

关于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被编译器视为无用代码进行了消除。

标签:swtich,case,goto,代码,标号,break,跳转
From: https://www.cnblogs.com/xieqisheng666/p/16963333.html

相关文章

  • Access中替代SQL Server的case when语句的办法
    最近在做一个用Access的东东,其中用到了casewhen的方式,但是Access是不支持这种语法的,查询知道IIf和Swith可以作为替代,总结如下:IIf函数IIf(expr,truepart,falsepart)......
  • mysql中的case语句
    1。selectname,casewhenbirthday<'1981'then'old'whenbirthday>'1988'then'yong'else'ok'ENDYORNfromlee;2。selectNA......
  • SqlServer 中 case when 的的两种写法
    https://mp.weixin.qq.com/s?src=11&timestamp=1670070823&ver=4204&signature=OpXckzt0JIEqamYo0WpJqwgtbQDMFkUpQ0Nc56WLqzHq0bMR91TRHbCxycSCx49JmQNO9K7MCZ-XLqzjJeTnS......
  • mysql case when then用法(转)
    mysqlcasewhenthen用法(转)原文:https://www.cnblogs.com/Richardzhu/p/3571670.htmlcase具有两种格式。简单case函数和case搜索函数。--简单case函数casesexwhe......
  • kubernetes中Deployment和replicaset关系剖析
    kubernetes中Deployment和replicaset关系剖析 前言:本片文章主要介绍了Deployment和Replicaset之间的关系以及如何产生Pod#vimnginx-deploy.yaml  #先给出De......
  • 测试比较if else与switch case
    #include<iostream>staticconstintLOOP=10000000;staticconstintN=10;voidtest_if_else(){for(inti=0;i<LOOP;i++){intsum=0;f......
  • QT+VS 调用基于Google Breakpad的跨平台Qt崩溃异常捕获调用方案
    方案一、基于GoogleBreakpad的跨平台Qt崩溃异常捕获调用方案首先上博客:Windows下Qt生成dump文件并定位bug(基于qBreakpad)这个地方使用的是一个叫qBreakPad的方案,这个之前......
  • 练习_(if、case)多系统配置yum源
    #!/usr/bash/binyum_server=192.168.201.130os_version=`cat/etc/redhat-release|awk'{print$4}'|awk-F"."'{print$1"."$2}'`[-d/etc/yum.repos.d]||mk......
  • JS基础12--break和continue
    <!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0,maxim......
  • ClearCase是全球领先的软件配置管理工具
    ClearCase是全球领先的软件配置管理工具,而VisualStudio2005是微软推出的强大的.Net开发工具。微软的VSIP计划为VisualStudio提供了界面的可扩展性,通过VSIP,ClearCase将自......