java的switch支持String类型的原理
Java的Switch从1.7之后开始支持String类型,那么是怎么做到的那?
下面是一个简单的测试,将TestSwitchString.class用javap进行反编译,查看字节码。可以看到在17行先调用了String.HashCode()方法,再执行的switch,switch中的3614、3614恰好是s1、s2的hashCode。这说明JVM会前取hashCode,再用hashCode进行比较,实际上还是int类型的比较。
TestSwitchString.java
package me.zhao.test;
public class TestSwitchString {
public static void main(String[] args) {
String s = "s1";
switch (s) {
case "s1":
System.out.println("s1");
break;
case "s2":
System.out.println("s2");
break;
default:
break;
}
}
}
TestSwitchString.class
javap -c .\TestSwitchString.class
Compiled from "TestSwitchString.java"
public class me.zhao.test.TestSwitchString {
public me.zhao.test.TestSwitchString();
Code:
0: aload_0
1: invokespecial #8 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #16 // String s1
2: astore_1
3: aload_1
4: dup
5: astore_2
6: invokevirtual #18 // Method java/lang/String.hashCode:()I
9: lookupswitch { // 2
3614: 36
3615: 48
default: 82
}
36: aload_2
37: ldc #16 // String s1
39: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
42: ifne 60
45: goto 82
48: aload_2
49: ldc #28 // String s2
51: invokevirtual #24 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
54: ifne 71
57: goto 82
60: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream;
63: ldc #16 // String s1
65: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
68: goto 82
71: getstatic #30 // Field java/lang/System.out:Ljava/io/PrintStream;
74: ldc #28 // String s2
76: invokevirtual #36 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
79: goto 82
82: return
}