Switch statements with strings are compiled with hashCode comparison, so the code:
switch(s){
case "1":
case "2":
case "3":
}
after compilation looks like:
switch(s.hashCode()){
case "1".hashCode():
case "2".hashCode():
case "3".hashCode():
}
Actually 7th JVM did not add anything specific about working with Strings in switches. Just a little compilation trick. Its possible to compare Strings by hashCode(), because this function is overridden and is based on object's content. This information is present at compile time. While its legal for Strings such approach is absolutely unacceptable for arbitrary object, because hashCode() returns a random number.
That's how it looks in bytecode:
11: tableswitch { // 49 to 51
49: 36 // "1".hashCode()
50: 50 // "2".hashCode()
51: 64 // "3".hashCode()
default: 75
}
36: aload_2
37: ldc #4 // String 1
39: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
42: ifeq 75
45: iconst_0
46: istore_3
47: goto 75
50: aload_2
51: ldc #6 // String 2
53: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
56: ifeq 75
59: iconst_1
60: istore_3
61: goto 75
64: aload_2
65: ldc #7 // String 3
67: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
70: ifeq 75
73: iconst_2
74: istore_3
75: iload_3
76: tableswitch { // 0 to 2
0: 104
1: 104
2: 104
default: 104
}
104: return
Switch with Strings is compiled to switch with ints. If accidentally two hash codes are equal, strings are compared with equals() method. Compiling switches from JVM specification.