网站设计的公司概况简介,discuz网站模板,网站建设实施流程图,网站设计软件microsoft2013对于int的switch#xff0c;jvm是用tableswitch和lookupswitch来实现的#xff0c;jdk1.7 switch增加了对string的支持#xff0c;那么底层是如何实现的呢#xff1f;是否增加了新的指令或是否给某些指令增加了新的含义#xff1f; 看这样一个程序#xff1a; Java代码 …对于int的switchjvm是用tableswitch和lookupswitch来实现的jdk1.7 switch增加了对string的支持那么底层是如何实现的呢是否增加了新的指令或是否给某些指令增加了新的含义 看这样一个程序 Java代码 public class Test { public static void main(String[] args) { String name b; int value 0; switch(name) { case a: value 1; break; case b: value 2; break; case c: value 3; break; case d: value 4; break; case e: value 5; break; default: value 6; } System.out.println(value); } } javap -c Test得出的结果为 Java代码 public static void main(java.lang.String[]); Code: 0: ldc #2 // String b 2: astore_1 //将b赋值给name 3: iconst_0 //将0入栈 4: istore_2 //将0赋值给value 5: aload_1 //将name即b入栈 6: astore_3 //将name即b赋值给一个编译器生成的变量记为tmpNametmpName此时也是b 7: iconst_m1 //将-1入栈 8: istore 4 //将-1赋值给一个编译器生成的变量记为m1 10: aload_3 //将tmpName即b入栈 11: invokevirtual #3 // Method java/lang/String.hashCode:()I 调用tmpName的hashCode方法b.hashCode()得结果98 14: tableswitch { // 97 to 101 //根据hashCode的值到不同的分支 97: 48 98: 63 //这里走到这个分支跳转到63 99: 78 100: 93 101: 108 default: 120 } 48: aload_3 49: ldc #4 // String a 51: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 54: ifeq 120 57: iconst_0 58: istore 4 60: goto 120 63: aload_3 //从14跳转到了这里将tmpName即b入栈 64: ldc #2 // String b 将b入栈 66: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z //比较tmpName和b如果相等将1入栈不等将0入栈.这里是相等的入栈的为1 69: ifeq 120 //从栈顶取出比较结果如果等于0就跳到120如果不等于0就继续下面的指令这里显然不等于0 72: iconst_1 //将1入栈 73: istore 4 //将1存储到m1中 75: goto 120 //跳到120 78: aload_3 79: ldc #6 // String c 81: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 84: ifeq 120 87: iconst_2 88: istore 4 90: goto 120 93: aload_3 94: ldc #7 // String d 96: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 99: ifeq 120 102: iconst_3 103: istore 4 105: goto 120 108: aload_3 109: ldc #8 // String e 111: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;)Z 114: ifeq 120 117: iconst_4 118: istore 4 120: iload 4 //将m1即73行存进去的1的值入栈 122: tableswitch { // 0 to 4 0: 156 1: 161 //这里走1这个分支跳到161 2: 166 3: 171 4: 176 default: 181 } 156: iconst_1 157: istore_2 158: goto 184 161: iconst_2 //将2入栈 162: istore_2 //将2存储到value 163: goto 184 //跳转到184进行打印输出 166: iconst_3 167: istore_2 168: goto 184 171: iconst_4 172: istore_2 173: goto 184 176: iconst_5 177: istore_2 178: goto 184 181: bipush 6 183: istore_2 184: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream; 187: iload_2 188: invokevirtual #10 // Method java/io/PrintStream.println:(I)V 191: return 在这一堆指令中我们发现jdk1.7并没有新指令来处理string switch还是继续用lookupswitch和tableswitch两个指令来处理的也没有扩展这两个指令它们还是只能处理int。 在11行我们看到调用了需要switch的string的hashCode方法并对该hashCode进行switch并跳转到相应的处理指令。跳到新的指令处我们发现这里63行将待switch的变量name与case中的值bequals了一下。这样做是为了避免不同的string有相同的hashCode确定equals返回true后编译器生成了一个处理value的switch源码里有多少个case编译器生成的tableswitch就有多少个分支最终会找到相应的处理分支完成string switch的处理。 接下来看一个不同string hashCode相等的版本 buzzards与righto的hashCode相等 hierarch与crinolines的hashCode相等 这里选择buzzards和righto Java代码 public class Test { public static void main(String[] args) { String name buzzards; int value 0; switch(name) { case buzzards: value 1; break; case righto: value 2; break; default: value 6; } System.out.println(value); } } 字节码 Java代码 public static void main(java.lang.String[]); Code: 0: ldc #2 // String buzzards 2: astore_1 3: iconst_0 4: istore_2 5: aload_1 6: astore_3 7: iconst_m1 8: istore 4 10: aload_3 11: invokevirtual #3 // Method java/lang/String.hashCode:()I 14: lookupswitch { // 1 -931102253: 32 default: 59 } 32: aload_3 33: ldc #4 // String righto 35: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;) 38: ifeq 47 41: iconst_1 42: istore 4 44: goto 59 47: aload_3 48: ldc #2 // String buzzards 50: invokevirtual #5 // Method java/lang/String.equals:(Ljava/lang/Object;) 53: ifeq 59 56: iconst_0 57: istore 4 59: iload 4 61: lookupswitch { // 2 0: 88 1: 93 default: 98 } 88: iconst_1 89: istore_2 90: goto 101 93: iconst_2 94: istore_2 95: goto 101 98: bipush 6 100: istore_2 101: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream; 104: iload_2 105: invokevirtual #7 // Method java/io/PrintStream.println:(I)V 108: return 这里我们看到两个字符串都跳到32行首先跟righto比较如果不相等则跳到47行比较buzzards。转载于:https://www.cnblogs.com/zhangyfr/p/8493950.html