Java7之后的版本才开始支持switch字符串,但是内部实现case还是基于整形变量的匹配。下面编写一个使用switch字符串的sample来看下。
package org.sun.sample.pojo;
/**
* Created by aron on 16-4-11.
*/
public class SwitchSample {
public static final String RED= "RED";
public static final String BLUE= "BLUE";
public static final String GREEN= "GREEN";
public void executeSwitch(String color) {
switch (color) {
case SwitchSample.RED:
System.out.println(color);
break;
case SwitchSample.BLUE:
System.out.println(color);
break;
case SwitchSample.GREEN:
System.out.println(color);
break;
default:
System.out.println("not match !!!");
}
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.sun.sample.pojo;
public class SwitchSample {
public static final String RED = "RED";
public static final String BLUE = "BLUE";
public static final String GREEN = "GREEN";
public SwitchSample() {
}
public void executeSwitch(String color) {
byte var3 = -1;
switch(color.hashCode()) {
case 81009:
if(color.equals("RED")) {
var3 = 0;
}
break;
case 2041946:
if(color.equals("BLUE")) {
var3 = 1;
}
break;
case 68081379:
if(color.equals("GREEN")) {
var3 = 2;
}
}
switch(var3) {
case 0:
System.out.println(color);
break;
case 1:
System.out.println(color);
break;
case 2:
System.out.println(color);
break;
default:
System.out.println("not match !!!");
}
}
}
Classfile /home/aron/workspace/idea/sun-sample/target/classes/org/sun/sample/pojo/SwitchSample.class
Last modified 2016-4-11; size 975 bytes
MD5 checksum 77db58f6c9ecac22549a85e042043490
Compiled from "SwitchSample.java"
public class org.sun.sample.pojo.SwitchSample
minor version: 0
major version: 52
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #11.#31 // java/lang/Object."<init>":()V
#2 = Methodref #32.#33 // java/lang/String.hashCode:()I
#3 = String #12 // RED
#4 = Methodref #32.#34 // java/lang/String.equals:(Ljava/lang/Object;)Z
#5 = String #15 // BLUE
#6 = String #16 // GREEN
#7 = Fieldref #35.#36 // java/lang/System.out:Ljava/io/PrintStream;
#8 = Methodref #37.#38 // java/io/PrintStream.println:(Ljava/lang/String;)V
#9 = String #39 // not match !!!
#10 = Class #40 // org/sun/sample/pojo/SwitchSample
#11 = Class #41 // java/lang/Object
#12 = Utf8 RED
#13 = Utf8 Ljava/lang/String;
#14 = Utf8 ConstantValue
#15 = Utf8 BLUE
#16 = Utf8 GREEN
#17 = Utf8 <init>
#18 = Utf8 ()V
#19 = Utf8 Code
#20 = Utf8 LineNumberTable
#21 = Utf8 LocalVariableTable
#22 = Utf8 this
#23 = Utf8 Lorg/sun/sample/pojo/SwitchSample;
#24 = Utf8 executeSwitch
#25 = Utf8 (Ljava/lang/String;)V
#26 = Utf8 color
#27 = Utf8 StackMapTable
#28 = Class #42 // java/lang/String
#29 = Utf8 SourceFile
#30 = Utf8 SwitchSample.java
#31 = NameAndType #17:#18 // "<init>":()V
#32 = Class #42 // java/lang/String
#33 = NameAndType #43:#44 // hashCode:()I
#34 = NameAndType #45:#46 // equals:(Ljava/lang/Object;)Z
#35 = Class #47 // java/lang/System
#36 = NameAndType #48:#49 // out:Ljava/io/PrintStream;
#37 = Class #50 // java/io/PrintStream
#38 = NameAndType #51:#25 // println:(Ljava/lang/String;)V
#39 = Utf8 not match !!!
#40 = Utf8 org/sun/sample/pojo/SwitchSample
#41 = Utf8 java/lang/Object
#42 = Utf8 java/lang/String
#43 = Utf8 hashCode
#44 = Utf8 ()I
#45 = Utf8 equals
#46 = Utf8 (Ljava/lang/Object;)Z
#47 = Utf8 java/lang/System
#48 = Utf8 out
#49 = Utf8 Ljava/io/PrintStream;
#50 = Utf8 java/io/PrintStream
#51 = Utf8 println
{
public static final java.lang.String RED;
descriptor: Ljava/lang/String;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String RED
public static final java.lang.String BLUE;
descriptor: Ljava/lang/String;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String BLUE
public static final java.lang.String GREEN;
descriptor: Ljava/lang/String;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL
ConstantValue: String GREEN
public org.sun.sample.pojo.SwitchSample();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=1, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 6: 0
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lorg/sun/sample/pojo/SwitchSample;
public void executeSwitch(java.lang.String);
descriptor: (Ljava/lang/String;)V
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=2
0: aload_1
1: astore_2
2: iconst_m1
3: istore_3
4: aload_2
5: invokevirtual #2 // Method java/lang/String.hashCode:()I
8: lookupswitch { // 3
81009: 44
2041946: 58
68081379: 72
default: 83
}
44: aload_2
45: ldc #3 // String RED
47: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
50: ifeq 83
53: iconst_0
54: istore_3
55: goto 83
58: aload_2
59: ldc #5 // String BLUE
61: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
64: ifeq 83
67: iconst_1
68: istore_3
69: goto 83
72: aload_2
73: ldc #6 // String GREEN
75: invokevirtual #4 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
78: ifeq 83
81: iconst_2
82: istore_3
83: iload_3
84: tableswitch { // 0 to 2
0: 112
1: 122
2: 132
default: 142
}
112: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
115: aload_1
116: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
119: goto 150
122: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
125: aload_1
126: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
129: goto 150
132: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
135: aload_1
136: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
139: goto 150
142: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream;
145: ldc #9 // String not match !!!
147: invokevirtual #8 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
150: return
LineNumberTable:
line 14: 0
line 16: 112
line 17: 119
line 19: 122
line 20: 129
line 22: 132
line 23: 139
line 25: 142
line 27: 150
LocalVariableTable:
Start Length Slot Name Signature
0 151 0 this Lorg/sun/sample/pojo/SwitchSample;
0 151 1 color Ljava/lang/String;
StackMapTable: number_of_entries = 9
frame_type = 253 /* append */
offset_delta = 44
locals = [ class java/lang/String, int ]
frame_type = 13 /* same */
frame_type = 13 /* same */
frame_type = 10 /* same */
frame_type = 28 /* same */
frame_type = 9 /* same */
frame_type = 9 /* same */
frame_type = 9 /* same */
frame_type = 249 /* chop */
offset_delta = 7
}
SourceFile: "SwitchSample.java"
可以看出来,这些整型变量是Method java/lang/String.hashCode,是字符串的hashCode值。在查看下hashCode的源代码即可发现hashCode是怎么生成的了。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
所以81009就是"RED".hashCode()值。写短代码测试下。
package org.sun.sample;
/**
* 启动类
*/
public class Bootstrap {
public static void main(String[] args) {
System.out.println(new String("RED").hashCode());
}
}