switch(jdk8)
本质
字节码
int类型
1 int = 4 byte
public static void switchTest(int a) { switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("3"); break; } } 字节码: 0 iload_0 1 lookupswitch 2 1: 28 (+27) 2: 39 (+38) default: 50 (+49) 28 getstatic #3 <java/lang/System.out> ...
switch的case <3 时,使用的lookupswitch指令实现;
lookupswitch
Access jump table by key match and jump 通过key匹配访问
The key must be of type int and is popped from the operand stack.
key 必须是int类型;
The key is compared against the match values.
If it is equal to one of them, then a target address is calculated by adding the corresponding offset to the address of the opcode of this lookupswitch instruction.
If the key does not match any of the match values, the target address is calculated by adding default to the address of the opcode of this lookupswitch instruction.
如果没有匹配的key,将会使用default;
Execution then continues at the target address.
public static void switchTest(int a) { switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; case 3: System.out.println("3"); break; default: System.out.println("default"); break; } } 字节码: 0 iload_0 1 tableswitch 1 to 3 1: 28 (+27) 2: 39 (+38) 3: 50 (+49) default: 61 (+60) 28 getstatic #3 <java/lang/System.out> ...
switch的case >=3 时,使用的tableswitch 指令实现;
tableswitch
Access jump table by index and jump 通过index访问
The index must be of type int and is popped from the operand stack. index必须是int类型;
If index is less than low or index is greater than high, then a target address is calculated by adding default to the address of the opcode of this tableswitch instruction.
Otherwise, the offset at position index - low of the jump table is extracted.
The target address is calculated by adding that offset to the address of the opcode of this tableswitch instruction.
Execution then continues at the target address.
byte类型
1byte = 8 bit
public static void switchTestByte(byte a) { switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("3"); break; } } 字节码: 0 iload_0 1 lookupswitch 2 1: 28 (+27) 2: 39 (+38) default: 50 (+49) 28 getstatic #3 <java/lang/System.out> ...
short类型
1 short = 2 byte
public static void switchTestShort(short a) { switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("3"); break; } } 字节码: 0 iload_0 1 lookupswitch 2 1: 28 (+27) 2: 39 (+38) default: 50 (+49) 28 getstatic #3 <java/lang/System.out> ...
char类型
public static void switchTestChar(char a) { switch (a) { case 1: System.out.println("1"); break; case 2: System.out.println("2"); break; default: System.out.println("3"); break; } } 字节码: 0 iload_0 1 lookupswitch 2 1: 28 (+27) 2: 39 (+38) default: 50 (+49) 28 getstatic #3 <java/lang/System.out> ...
String类型
public static void switchTestString(String a) { switch (a) { case "a": System.out.println("a"); break; case "b": System.out.println("b"); break; default: System.out.println("default"); break; } } 字节码: 0 aload_0 1 astore_1 2 iconst_m1 3 istore_2 4 aload_1 5 invokevirtual #4 <java/lang/String.hashCode> //String 的hashCode值 8 lookupswitch 2 97: 36 (+28) // "a"的Hashcode值 98: 50 (+42) // "b"的Hashcode值 default: 61 (+53) 36 aload_1 37 ldc #2 <a> 39 invokevirtual #5 <java/lang/String.equals> 42 ifeq 61 (+19) 45 iconst_0 46 istore_2 47 goto 61 (+14) 50 aload_1 51 ldc #6 <b> 53 invokevirtual #5 <java/lang/String.equals> 56 ifeq 61 (+5) 59 iconst_1 60 istore_2 61 iload_2 ...
String类型本质:用的hashcode值,也是int类型;
Enum类型
enum MyEnum { A,B,C } public static void switchTestEnum(MyEnum myEnum) { switch (myEnum) { case A: System.out.println("a"); break; case B: System.out.println("b"); break; default: System.out.println("default"); break; } } 字节码: 0 getstatic #4 <classtest/SwitchTest$1.$SwitchMap$classtest$SwitchTest$MyEnum> 3 aload_0 4 invokevirtual #5 <classtest/SwitchTest$MyEnum.ordinal> //枚举的ordinal方法 7 iaload 8 lookupswitch 2 1: 36 (+28) 2: 47 (+39) default: 58 (+50) 36 getstatic #6 <java/lang/System.out> ...
enum本质 :enum类型的ordinal方法(当前枚举值在枚举类型的序号0下标起始);
为什么switch会有类型限制?
字节码 lookupswitch、tableswitch指令 要求key/index 必须是int类型;