码迷,mamicode.com
首页 > 编程语言 > 详细

java7(1)——反编译深入理解增强的switch

时间:2014-08-02 01:41:42      阅读:396      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   java   使用   strong   io   文件   

【本文介绍】

  本文主要讲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_1
12        1: astore_2                ---------------从这里开始------------
13        2: iconst_m1              // 将int型-1推送至栈顶
14        3: istore_3               // 赋值,因为此时栈顶元素为-1,所以赋值-1
15        4: aload_2
16        5: invokevirtual #2                  // Method java/lang/String.hashCode: 调用hasCode方法
17 ()I
18        8: lookupswitch  { // 2        源码本来只有一次switch,现在被拆分成两次,这是第一次switch,下面还有一次公共的
19                     97: 36           case 97 : 跳至36行 aload_2
20                     98: 50           case 98 :跳至50行 aload_2
21                default: 61           default : 跳至61行 iload_3
22           }
23       36: aload_2
24       37: ldc           #3                  // String a  下面equal的内容
25       39: invokevirtual #4                  // Method java/lang/String.equals:(L  进行equal的比较
26 java/lang/Object;)Z
27       42: ifeq          61           // if 语句
28       45: iconst_0               // 将int型0推送至栈顶
29       46: istore_3               // 赋值,因为此时栈顶元素为 0 ,所以赋值0
30       47: goto          61
31       50: aload_2
32       51: ldc           #5                  // String b   下面equal的内容
33       53: invokevirtual #4                  // Method java/lang/String.equals:(L  进行equal的比较
34 java/lang/Object;)Z
35       56: ifeq          61           // if 语句
36       59: iconst_1               // 将int型1推送至栈顶 
37       60: istore_3               // 赋值,因为此时栈顶元素为 1 , 所以赋值1
38       61: iload_3                ----------------到这里结束---------------
39       62: lookupswitch  { // 2
40                      0: 88
41                      1: 99
42                default: 110
43           }
44       88: getstatic     #6                  // Field java/lang/System.out:Ljava/
45 io/PrintStream;
46       91: ldc           #3                  // String a
47       93: invokevirtual #7                  // Method java/io/PrintStream.printl
48 n:(Ljava/lang/String;)V
49       96: goto          118
50       99: getstatic     #6                  // Field java/lang/System.out:Ljava/
51 io/PrintStream;
52      102: ldc           #5                  // String b
53      104: invokevirtual #7                  // Method java/io/PrintStream.printl
54 n:(Ljava/lang/String;)V
55      107: goto          118
56      110: getstatic     #6                  // Field java/lang/System.out:Ljava/
57 io/PrintStream;
58      113: ldc           #8                  // String default
59      115: invokevirtual #7                  // Method java/io/PrintStream.printl
60 n:(Ljava/lang/String;)V
61      118: return
62 }

 

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_1
12        1: lookupswitch  { // 2
13                      1: 28
14                      2: 39
15                default: 50
16           }
17       28: getstatic     #2                  // Field java/lang/System.out:Ljava/
18 io/PrintStream;
19       31: ldc           #3                  // String 1
20       33: invokevirtual #4                  // Method java/io/PrintStream.printl
21 n:(Ljava/lang/String;)V
22       36: goto          58
23       39: getstatic     #2                  // Field java/lang/System.out:Ljava/
24 io/PrintStream;
25       42: ldc           #5                  // String 2
26       44: invokevirtual #4                  // Method java/io/PrintStream.printl
27 n:(Ljava/lang/String;)V
28       47: goto          58
29       50: getstatic     #2                  // Field java/lang/System.out:Ljava/
30 io/PrintStream;
31       53: ldc           #6                  // String default
32       55: invokevirtual #4                  // Method java/io/PrintStream.printl
33 n:(Ljava/lang/String;)V
34       58: return
35 }

  大家看到这么多字节码是不是有点头晕不想再看下去了?其实只需稍稍观察比较就能发现”从这里开始“——”到这里结束“中间那些字节码是下面那个字节码文件所没有的,所以我们研究这几行代码就行了。又看我用红色字体标出来的注释,结果就显而易见了:

(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 }

 

java7(1)——反编译深入理解增强的switch,布布扣,bubuko.com

java7(1)——反编译深入理解增强的switch

标签:style   blog   color   java   使用   strong   io   文件   

原文地址:http://www.cnblogs.com/xiaoMzjm/p/3885990.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!