Java switch to achieve a thorough understanding of the principles of

Java official document describes:

A switch works with the byte, short, char, and int primitive data types. It also works with enumerated types, the String class, and a few special classes that wrap certain primitive types: Character, Byte, Short, and Integer

In the basic data types byte / char

public class SwitchBasicTest {
    
    private int switchByte(byte i) {
        int ret;
        switch (i) {
            case 0:
                ret = 10;
                break;
            case 1:
                ret = 11;
                break;
            default:
                ret = 0;
        }

        return ret;
    }
    private int switchChar(char i) {
        int ret;
        switch (i) {
            case 0:
                ret = 10;
                break;
            case 1:
                ret = 11;
                break;
            case 'a':
                ret = 20;
                break;
            case '写':
                ret = 21;
                break;
            default:
                ret = 0;
        }

        return ret;
    }
}
复制代码

Javap -v or use other tools to decompile SwitchBasicTest.class, as used herein, IDEA plug-injclasslib Bytecode viewer

Decompile obtain switchBytebytecodes method:

 0 iload_1
 1 lookupswitch 2
        0:  28 (+27)
        1:  34 (+33)
        default:  40 (+39)
28 bipush 10
30 istore_2
31 goto 42 (+11)
34 bipush 11
36 istore_2
37 goto 42 (+5)
40 iconst_0
41 istore_2
42 iload_2
43 ireturn

复制代码

switchChar The method bytecode:

 0 iload_1
 1 lookupswitch 4
        0:  44 (+43)
        1:  50 (+49)
        97:  56 (+55)
        20889:  62 (+61)
        default:  68 (+67)
44 bipush 10
46 istore_2
47 goto 70 (+23)
50 bipush 11
52 istore_2
53 goto 70 (+17)
56 bipush 20
58 istore_2
59 goto 70 (+11)
62 bipush 21
64 istore_2
65 goto 70 (+5)
68 iconst_0
69 istore_2
70 iload_2
71 ireturn

复制代码

It is known for byteother basic data types, switchthe direct use integer comparison

  • byte, short value can be transferred directly whole
  • char takes unicodeinteger code value
  • Integer and other packaging types, calls the intValuemethod of obtaining the value of the integer variable

In the role of String (version JDK1.7 and later)

public class SwitchBasicTest {
    private int switchString(String i) {
            int ret;
            switch (i) {
                case "0":
                    ret = 10;
                    break;
                case "1":
                    ret = 11;
                    break;
                case "a":
                    ret = 20;
                    break;
                default:
                    ret = 0;
            }
    
            return ret;
        }
}
复制代码

Use IDEA editor, open the file .class see decompile the code:

public class SwitchBasicTest {
    private int switchString(String i) {
        byte var4 = -1;
        switch(i.hashCode()) {
        case 48:
            if (i.equals("0")) {
                var4 = 0;
            }
            break;
        case 49:
            if (i.equals("1")) {
                var4 = 1;
            }
            break;
        case 97:
            if (i.equals("a")) {
                var4 = 2;
            }
        }

        byte ret;
        switch(var4) {
        case 0:
            ret = 10;
            break;
        case 1:
            ret = 11;
            break;
        case 2:
            ret = 20;
            break;
        default:
            ret = 0;
        }

        return ret;
    }
}
复制代码

Decompile obtained switchStringbytecodes:

  0 aload_1
  1 astore_3
  2 iconst_m1
  3 istore 4
  5 aload_3
  6 invokevirtual #8 <java/lang/String.hashCode>
  9 lookupswitch 3
        48:  44 (+35)
        49:  59 (+50)
        97:  74 (+65)
        default:  86 (+77)
 44 aload_3
 45 ldc #9 <0>
 47 invokevirtual #10 <java/lang/String.equals>
 50 ifeq 86 (+36)
 53 iconst_0
 54 istore 4
 56 goto 86 (+30)
 59 aload_3
 60 ldc #11 <1>
 62 invokevirtual #10 <java/lang/String.equals>
 65 ifeq 86 (+21)
 68 iconst_1
 69 istore 4
 71 goto 86 (+15)
 74 aload_3
 75 ldc #12 <a>
 77 invokevirtual #10 <java/lang/String.equals>
 80 ifeq 86 (+6)
 83 iconst_2
 84 istore 4
 86 iload 4
 88 tableswitch 0 to 2	
        0:  116 (+28)
        1:  122 (+34)
        2:  128 (+40)
        default:  134 (+46)
116 bipush 10
118 istore_2
119 goto 136 (+17)
122 bipush 11
124 istore_2
125 goto 136 (+11)
128 bipush 20
130 istore_2
131 goto 136 (+5)
134 iconst_0
135 istore_2
136 iload_2
137 ireturn
复制代码

We can see the switcheffect in Stringthe final split into two for integer switchstatements, specific procedures:

  • Calculated and compared hashcode
  • If the same hashcode, it is further used equalsto determine the content of the same string, treated in the same case where two strings hashcode

Acting under enumeration

public enum SeasonEnum {
    SPRING, SUMMER, AUTUMN, WINTER
}

public class SwitchEnumTest {
   
    private static int testSpring(SeasonEnum seasonEnum) {
        int ret;
        switch (seasonEnum) {
            case AUTUMN:
                ret = 1;
                break;
            case SPRING:
                ret = 2;
                break;
            case SUMMER:
                ret = 3;
                break;
            case WINTER:
                ret = 4;
                break;
            default:
                ret = 5;
        }
        return ret;
    }
}
复制代码

Decompile obtain testSpringbytecodes method:

 0 getstatic #6 <xx/SwitchEnumTest$1.$SwitchMap$xx$enumt$SeasonEnum>
 3 aload_0
 4 invokevirtual #7 <xx/enumt/SeasonEnum.ordinal>
 7 iaload
 8 tableswitch 1 to 4	1:  40 (+32)
        2:  45 (+37)
        3:  50 (+42)
        4:  55 (+47)
        default:  60 (+52)
40 iconst_1
41 istore_1
42 goto 62 (+20)
45 iconst_2
46 istore_1
47 goto 62 (+15)
50 iconst_3
51 istore_1
52 goto 62 (+10)
55 iconst_4
56 istore_1
57 goto 62 (+5)
60 iconst_5
61 istore_1
62 iload_1
63 ireturn
复制代码

can be seen: 4 invokevirtual #7 <xx/enumt/SeasonEnum.ordinal>

That is, switchwhen acting on the enumeration, enumeration calls the ordinalmethod that ultimately intvalue comparison

lookupswitch 和 tableswitch

  • tableswitch Using an array data structure can be positioned by the jump destination line of the subscripts
  • lookupswitch The number of lines to maintain the relationship between a key-value, a jump by one by comparing the index to find matches to be of
  • tableswitchThan lookupswitchbetter lookup performance
  • switchStatement casewhen the branch condition value sparse, tableswitchspatial low usage instructions, may be used in this case lookupswitchinstruction

in conclusion

  • switch The syntax is actually only valid for integer parameters
  • breakAt the bytecode level generates a gotostatement casewithout tape breakdirectly to the next time a caselogical
  • switchActing on the enumeration actually uses the enumeration ordinalmethod returns a value as a basis for comparison
  • switchActing on the string when the character string hashcodeas a basis for comparison, hashcodethe same is further used equalsto compare strings content
  • The java virtual machine specification, java virtual machine tableswitchand the lookupswitchinstructions only support an int conditions, it switchdoes not support longLong

Information Reference

Guess you like

Origin juejin.im/post/5e8d8b62e51d4546ca30ad43