• java条件判断语句switch小结


      java的流程控制语句中,选择判断语句有两种if...else和switch。相对而言,switch在实际使用过程中需要注意的地方较多,有时会由于忘记它的一些语法特征,对其语法产生误解,从而导致一些错误。这里通过查阅资料和编码实践对switch做出一些小结。

    一、switch的基本语法

      switch的基本语法结构为

    switch (表达式){
        case 常量1:
            // 代码块1;
            break;
        case 常量2:
        // 代码块2; 
        break; 
      default:  
        // 代码块n; 
        break; 
    }

      switch条件判断语句涉及四个关键字:switch、case、default、break

      switch:表示条件表达式,括号里的值是一个规定数据类型的值。

      case:表示条件分支,case后面跟一个常量,每个case后面的值必须不一样。case的个数可以为0个。

      default:表示默认分支,default可以省略,通常放在最后。

      break:表示“停止”,跳出当前switch语句。

    二、switch支持的数据类型

      switch()括号中的表达式的结果的类型只能是特定类型,我们将一个double类型的变量放入,发现编译报错:Cannot switch on a value of type double. Only convertible int values, strings or enum variables are permitted。

      不难看出这里括号中只支持是int,String,enum型的。

      由于java中的类型的自动转型,byte、char、short这三种可以自动转换为int型的类型括号中也支持。

      由于java中包装类的自动拆箱,Integer、Byte、Char、Short这四种类型括号中也支持。

      总结来说:switch()括号中的表达式支持int、String、enum以及可以自动转型为int的其他类型。

      注意:在Java1.6中表达式的类型只能为int和enum,在java1.7后支持了对String的判断,String类型比较特殊,后续会讲到。

    三、switch的执行顺序

      switch的执行顺序如下:

      1.先计算并获得switch后面小括号里的表达式或变量的值,然后将计算结果按照代码顺序与每个case后的常量比较。当二者相等时,执行这个case块中的代码块;若case后的常量与该值都不相等且default存在,则执行default中个代码块;若若case后的常量与该值都不相等且default不存在,则switch语句执行结束

      2.当开始执行一个条件分支的代码(case中的常量与switch后的结果相等,或进入default后的代码块),会从该代码块开始,跳过剩余的条件判断,从上至下执行代码块,直到遇到break或执switch中之后的代码块全部执行完毕。例子如下:

        // 例一
        int i = 1;
        switch ( i ) {
        case 1:
            System.out.println(1);
        case 2:
            System.out.println(2);
        default :
            System.out.println("default");
        case 3:
            System.out.println(3);
            break;
        case 4:
            System.out.println(4);
            break;
        }
        // 例一执行结果
        1
        2
        default
        3
    
        // 例二
        int i = 5;
        switch ( 5 ) {
        case 1:
            System.out.println(1);
            break;
        case 2:
            System.out.println(2);
            break;
        default :
            System.out.println("default");
        case 3:
            System.out.println(3);
            break;
        case 4:
            System.out.println(4);
            break;
        }
        // 例二执行结果
        default
        3

    四、switch使用中的注意事项

      1.case后面必须跟常量,如果是变量,必须是final修饰的在编译时可识别的一般类型变量或字符串(包括包装类在内的其他引用类型都不可以),本质上也是常量。

      如:final int a1 = 1;       case a1;      // 正确
        final int a2;          case a2;      // 异常 The local variable i may not have been initialized
        final Integer = 3;       case a3;      // 异常 case expressions must be constant expressions
        final String a4 = "hello"; case a4;      // 正确

      2.switch在进入某条件分支后(case或default)会一直往下执行代码,直到遇到break。这点上面有例子讲到。

      3.switch使用枚举进行选择判断时,在switch()的括号中要指定枚举类名.枚举常量名,case后直接接该枚举类的枚举常量名。

        enum Season{
            SPRING, SUMMER, AUTUMN, WINTER;
        }
        public static void main(String[] args) {        
            Season season = Season.SPRING ;
            switch ( season ) {
            case SPRING:
                System.out.println("spring");
                break;
            case SUMMER:
                System.out.println("summer");
                break;
            case AUTUMN:
                System.out.println("antumn");
                break;
            case WINTER:
                System.out.println("winter");
                break;
            }
        }

      编译后实际上switch()括号中的值,case后接的值,与对应枚举常量在枚举类中的序数有关,从代码看是序数+1,具体实现原理这里看不出来。反编译后的代码如下,不同环境下反编译结果不一样,但可以看出原理是一样的。

        Season season = Season.SPRING;
        switch ($SWITCH_TABLE$com$test$processControl$SwitchTest$Season()[season.ordinal()])
        {
        case 1:
          System.out.println("spring");
          break;
        case 2:
          System.out.println("summer");
          break;
        case 3:
          System.out.println("antumn");
          break;
        case 4:
          System.out.println("winter");
        }
      }

      4.switch使用String进行选择判断时,编译后实际上switch()括号中的值,case后接的值都是对应字符串的哈希值,且判断哈希值后会再次用equls()方法判断是否是同一个字符串。

        String str = "a";
        String str1;
        switch ((str1 = str).hashCode())
        {
        case 98:
          if (str1.equals("b"));
          break;
        case 99:
          if (!(str1.equals("c"))) { break label82:
    
            System.out.println("b");
          }
          else {
            System.out.println("c"); }
          break;
        default:
          label82: System.out.println("default");
        }

      不通环境下反编译结果不一,为方便理解,我们可以将上述代码理解为以下逻辑

            String str = "a";
            String str1 = str;
            switch ( str1.hashCode() ){
                case 98:        // "b".hashCode();
                    if( str1.equals("b") ){
                        System.out.println("b");
                    }
                    break;
                case 99:        // "c".hashCode();
                    if ( str1.equals("c") ) { 
                        System.out.println("c");
                      }
                    break;
                default: 
                    System.out.println("default");
            }
  • 相关阅读:
    Spring 源码学习
    Feign Client 原理和使用
    算法基础:排序算法看这一篇就够了
    Spring 源码学习2
    Spring 源码学习
    最优包裹组合-贪心算法
    @Transactional 事务的底层原理
    Mysql索引扫盲总结
    snowflake原理解析
    分布式ID总结
  • 原文地址:https://www.cnblogs.com/James-Gong/p/8182379.html
Copyright © 2020-2023  润新知