首页 > 代码库 > java7(1)——反编译深入理解增强的switch
java7(1)——反编译深入理解增强的switch
【本文介绍】
本文主要讲java_7 的改进switch的底层实现。反编译一个使用带String的switch的demo并一步步解析反编译出来的字节码,从编译的角度解读switch的底层实现。
【正文】
在java7中,switch()可以放进去String 类型了,这无非是一大便利。底层JVM的swtich并没有真正的改进,只是在编译阶段,编译器把关于String的switch拆分成if语句而已。
我们写一个简单的例子测试一下:
(1)Test类:switch()使用String
public class Test { public void test(String str) { switch(str){ case "a": System.out.println("a");break; case "b": System.out.println("b");break; default : System.out.println("default"); } }}
(2)Test2类:switch()使用int
public class Test2 { public void test(int str) { switch(str){ case 1: System.out.println("1");break; case 2: System.out.println("2");break; default : System.out.println("default"); } }}
javac 编译 , javap -c 反编译 Test 后的结果:
1 public class Test { 2 public Test(); 3 Code: 4 0: aload_0 5 1: invokespecial #1 // Method java/lang/Object."<init>": 6 ()V 7 4: return 8 9 public void test(java.lang.String);10 Code:11 0: aload_112 1: astore_2 ---------------从这里开始------------13 2: iconst_m1 // 将int型-1推送至栈顶14 3: istore_3 // 赋值,因为此时栈顶元素为-1,所以赋值-115 4: aload_216 5: invokevirtual #2 // Method java/lang/String.hashCode: 调用hasCode方法17 ()I18 8: lookupswitch { // 2 源码本来只有一次switch,现在被拆分成两次,这是第一次switch,下面还有一次公共的19 97: 36 case 97 : 跳至36行 aload_220 98: 50 case 98 :跳至50行 aload_221 default: 61 default : 跳至61行 iload_322 }23 36: aload_224 37: ldc #3 // String a 下面equal的内容25 39: invokevirtual #4 // Method java/lang/String.equals:(L 进行equal的比较26 java/lang/Object;)Z27 42: ifeq 61 // if 语句28 45: iconst_0 // 将int型0推送至栈顶29 46: istore_3 // 赋值,因为此时栈顶元素为 0 ,所以赋值030 47: goto 6131 50: aload_232 51: ldc #5 // String b 下面equal的内容33 53: invokevirtual #4 // Method java/lang/String.equals:(L 进行equal的比较34 java/lang/Object;)Z35 56: ifeq 61 // if 语句36 59: iconst_1 // 将int型1推送至栈顶 37 60: istore_3 // 赋值,因为此时栈顶元素为 1 , 所以赋值138 61: iload_3 ----------------到这里结束---------------39 62: lookupswitch { // 240 0: 8841 1: 9942 default: 11043 }44 88: getstatic #6 // Field java/lang/System.out:Ljava/45 io/PrintStream;46 91: ldc #3 // String a47 93: invokevirtual #7 // Method java/io/PrintStream.printl48 n:(Ljava/lang/String;)V49 96: goto 11850 99: getstatic #6 // Field java/lang/System.out:Ljava/51 io/PrintStream;52 102: ldc #5 // String b53 104: invokevirtual #7 // Method java/io/PrintStream.printl54 n:(Ljava/lang/String;)V55 107: goto 11856 110: getstatic #6 // Field java/lang/System.out:Ljava/57 io/PrintStream;58 113: ldc #8 // String default59 115: invokevirtual #7 // Method java/io/PrintStream.printl60 n:(Ljava/lang/String;)V61 118: return62 }
javac 编译 , javap -c 反编译 Test2 后的结果:
1 public class Test2 { 2 public Test2(); 3 Code: 4 0: aload_0 5 1: invokespecial #1 // Method java/lang/Object."<init>": 6 ()V 7 4: return 8 9 public void test(int);10 Code:11 0: iload_112 1: lookupswitch { // 213 1: 2814 2: 3915 default: 5016 }17 28: getstatic #2 // Field java/lang/System.out:Ljava/18 io/PrintStream;19 31: ldc #3 // String 120 33: invokevirtual #4 // Method java/io/PrintStream.printl21 n:(Ljava/lang/String;)V22 36: goto 5823 39: getstatic #2 // Field java/lang/System.out:Ljava/24 io/PrintStream;25 42: ldc #5 // String 226 44: invokevirtual #4 // Method java/io/PrintStream.printl27 n:(Ljava/lang/String;)V28 47: goto 5829 50: getstatic #2 // Field java/lang/System.out:Ljava/30 io/PrintStream;31 53: ldc #6 // String default32 55: invokevirtual #4 // Method java/io/PrintStream.printl33 n:(Ljava/lang/String;)V34 58: return35 }
大家看到这么多字节码是不是有点头晕不想再看下去了?其实只需稍稍观察比较就能发现”从这里开始“——”到这里结束“中间那些字节码是下面那个字节码文件所没有的,所以我们研究这几行代码就行了。又看我用红色字体标出来的注释,结果就显而易见了:
(0)用一个int类型变量代表String类型变量
(1)获取String字符串的hashCode
(2)case hashCode
(3)用if语句处理String
(4)为int类型的变量赋值
(5)真正的swtich,现在传入的是上面得出的int类型变量。
把上面的字节码文件翻译成java即:
1 public class test { 2 3 public void test(String str) { 4 5 int i = -1; 6 7 switch(str.hashCode()){ 8 9 case 97:10 if(str.equals("a")){11 i = 0;12 }13 break;14 case 98:15 if(str.equals("b")){16 break;17 }18 }19 20 switch(i) {21 22 case 0:23 System.out.println("a");24 break;25 26 case 1:27 System.out.println("b");28 break;29 30 default:31 System.out.println("default");32 }33 }34 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。