Java中多If else优化 (一)----分支结构If else/switch

一、If语句

If() { }

If() {} else {}

If() {} if() {} if() {}

If() {} else if() {} else if() {} else {}

说明:

    1) 可以进行嵌套,或者多重嵌套,但为保证代码逻辑清晰,提高可读性,尽量不要嵌套。

    2) 按先后顺序依次判断是否成立,当一个if 语句检测为真,后面的else if 及 else语句都将被跳过。

    在多分支条件下,若最多只有一个分支条件成立,使用If() {}  else if() {} else if() {} else {} ,且按分支出现概率从大到小排放条件表达式,即概率上出现最多的放在最前面,减少程序判断次数,提高效率。

    多分支同时成立且都需要处理的情况下,需使用If() {}  if() {} if() {}。


二、Switch语句

switch(expression){

    case value :

       //语句

       break; //可选

    case value :

       //语句

       break; //可选

    //你可以有任意数量的case语句

    default : //可选

       //语句

}

说明:

    1) switch 语句中的变量类型可以是: byte、short、int 或者 char。String(从Java SE 7 开始),同时case 标签必须为字符串常量或字面量。

    2) switch 语句可以拥有多个 case 语句。每个 case 后面跟一个要比较的值和冒号。

    3) case 语句中的值的数据类型必须与变量的数据类型相同,而且只能是常量或者字面常量。

    4) 当变量的值与 case 语句的值相等时, case 语句之后的语句开始执行,直到 break 语句出现才会跳出 switch 语句。如果没有 break 语句出现,程序会继续执行下一条 case 语句,直到出现 break 语句。

    5) switch 语句可以包含一个 default 分支,该分支必须是switch 语句的最后一个分支。default 在没有case 语句的值和变量值相等的时候执行。default 分支不需要 break 语句。


三、if与switch区别

    if...else顺序判断条件分支,遇到表达式值为真时,执行代码,而switch...case生成一个跳转表来指示实际的case分支的地址,跳转表的索引号与switch变量的值相等,通过对应索引号的表项从而到达定位分支的目的。若switch变量为String类型,会有两个跳转表,先将String类型对应为一个int类型,再通过该int类型跳转到对应的分支。


四、if 与switch比较

A) 时间

效率--仅从跳转次数来比较两者的效率, 不考虑编译器的优化和条件传送

分支较多时,大于3,switch效率高。

分支较少时,小于3,if...else结构更好

B)空间

switch...case占用较多的代码空间,因为它要生成跳表。

(特别是当case常量分布范围很大但实际有效值又比较少的情况,switch...case的空间利用率将变得较低。----未能深入理解)

C)适用范围

.switch...case只能处理case为常量(byte、short、int 或者 char。String(从Java SE 7 开始))的情况,对非常量的情况是无能为力的。例如 if (a > 1 && a < 100),是无法使用switch...case来处理的。所以,switch只能是在常量选择分支时比ifelse效率高,但是if else能应用于更多的场合,比较灵活。


五、Java中源码与字节码

    从字节码中可以看出switch中存在跳转表  ,类型为String时存在lookupswitch 和tableswitch两张,而为Int类型时只有lookupswitch, Goto语句对应的行号 , 跳转表内 冒号后也为行号 .

1、if else 

    @Test
    public void ifElseTest(int a) {

        if (a > 5) {
            System.out.println("a值 >5 ----");
        } else if (a > 10) {
            System.out.println("a值 >10 ----");
        } else if (a > 15) {
            System.out.println("a值 >15 ----");
        }
    }

字节码:

public ifElseTest(I)V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 15 L0
    ILOAD 1
    ICONST_5
    IF_ICMPLE L1
   L2
    LINENUMBER 16 L2
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "a\u503c >5 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L3
   L1
    LINENUMBER 17 L1
   FRAME SAME
    ILOAD 1
    BIPUSH 10
    IF_ICMPLE L4
   L5
    LINENUMBER 18 L5
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "a\u503c >10 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
    GOTO L3
   L4
    LINENUMBER 19 L4
   FRAME SAME
    ILOAD 1
    BIPUSH 15
    IF_ICMPLE L3
   L6
    LINENUMBER 20 L6
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "a\u503c >15 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L3
    LINENUMBER 22 L3
   FRAME SAME
    RETURN
   L7
    LOCALVARIABLE this Lpractice/basics/IfElseTest; L0 L7 0
    LOCALVARIABLE a I L0 L7 1
    MAXSTACK = 2
    MAXLOCALS = 2

2、switch case

变量为Int类型

    public void switchCaseIntTest(int str) {
        switch (str) {
        case 5:
            System.out.println("5 ----");
            break;
        case 10:
            System.out.println("10 ----" );
            break;
        case 15:
            System.out.println("15 ----");
            break;
        default:
            System.out.println("int值 ----");
        }
        System.out.println("intTest ----");
    }

 Java字节码

public switchCaseIntTest(I)V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 26 L0
    ILOAD 1
    LOOKUPSWITCH
      5: L1
      10: L2
      15: L3
      default: L4
   L1
    LINENUMBER 28 L1
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "5 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L5
    LINENUMBER 29 L5
    GOTO L6
   L2
    LINENUMBER 31 L2
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "10 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L7
    LINENUMBER 32 L7
    GOTO L6
   L3
    LINENUMBER 34 L3
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "15 ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L8
    LINENUMBER 35 L8
    GOTO L6
   L4
    LINENUMBER 37 L4
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "int\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L6
    LINENUMBER 39 L6
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "intTest ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L9
    LINENUMBER 40 L9
    RETURN
   L10
    LOCALVARIABLE this Lpractice/basics/IfElseTest; L0 L10 0
    LOCALVARIABLE str I L0 L10 1
    MAXSTACK = 2
    MAXLOCALS = 2

变量类型为String

 public void switchCaseStrTest(String str) {
        switch (str) {
        case "a":
            System.out.println("a值 ----");
            break;
        case "b":
            System.out.println("b值 ----" );
            break;
        case "x":
            System.out.println("x值 ----");
            break;
        case "z":
            System.out.println("z值 ----");
            break;
        default:
            System.out.println("abxz值 ----");
        }
        System.out.println("strTest ----");
    }

字节码:

public switchCaseStrTest(Ljava/lang/String;)V
  @Lorg/junit/Test;()
   L0
    LINENUMBER 44 L0
    ALOAD 1
    ASTORE 2
    ICONST_M1
    ISTORE 3
    ALOAD 2
    INVOKEVIRTUAL java/lang/String.hashCode ()I
    LOOKUPSWITCH
      97: L1
      98: L2
      120: L3
      122: L4
      default: L5
   L1
   FRAME APPEND [java/lang/String I]
    ALOAD 2
    LDC "a"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_0
    ISTORE 3
    GOTO L5
   L2
   FRAME SAME
    ALOAD 2
    LDC "b"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_1
    ISTORE 3
    GOTO L5
   L3
   FRAME SAME
    ALOAD 2
    LDC "x"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_2
    ISTORE 3
    GOTO L5
   L4
   FRAME SAME
    ALOAD 2
    LDC "z"
    INVOKEVIRTUAL java/lang/String.equals (Ljava/lang/Object;)Z
    IFEQ L5
    ICONST_3
    ISTORE 3
   L5
   FRAME SAME
    ILOAD 3
    TABLESWITCH
      0: L6
      1: L7
      2: L8
      3: L9
      default: L10
   L6
    LINENUMBER 46 L6
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "a\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L11
    LINENUMBER 47 L11
    GOTO L12
   L7
    LINENUMBER 49 L7
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "b\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L13
    LINENUMBER 50 L13
    GOTO L12
   L8
    LINENUMBER 52 L8
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "x\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L14
    LINENUMBER 53 L14
    GOTO L12
   L9
    LINENUMBER 55 L9
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "z\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L15
    LINENUMBER 56 L15
    GOTO L12
   L10
    LINENUMBER 58 L10
   FRAME SAME
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "abxz\u503c ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L12
    LINENUMBER 60 L12
   FRAME CHOP 2
    GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
    LDC "strTest ----"
    INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
   L16
    LINENUMBER 61 L16
    RETURN
   L17
    LOCALVARIABLE this Lpractice/basics/IfElseTest; L0 L17 0
    LOCALVARIABLE str Ljava/lang/String; L0 L17 1
    MAXSTACK = 2
    MAXLOCALS = 4 

参考文章:

https://www.cnblogs.com/ye-ming/articles/7942472.html

https://www.jb51.net/article/118488.htm


猜你喜欢

转载自blog.csdn.net/u012475575/article/details/80968050