转贴 jvm指令解析

Posted on 2011-09-23 13:55 xsong 阅读(329) 评论(0)  编辑  收藏 所属分类: java
//源代码

class TT{

       
static int tt = 5;

       
int t;

       
public TT(){

              System.out.println(
"TT");

       }

}

 

public class ArrayTest extends TT{

       
public ArrayTest(){

              
super();

              System.out.println(
"test");

       }    

       
static {

              
int c = 5;

       }

       
static int b = 1;

       
int A[] = {1,4,5,12,34,123,14,32};

      

       
static {

              
int d = 6;

       }

       
public static void main(String[] args) {

              ArrayTest a 
= new ArrayTest();

              
int i = 2;

              System.out.println(a.A[i
++]);

              System.out.println(i);

       }

}

//javap -c 反编译代码

D:\
>javap -c TT

Compiled from 
"ArrayTest.java"

class TT extends java.lang.Object{

static int tt;

 

int t;

 

public TT();

  Code:

   
0:   aload_0

   
1:   invokespecial   #1//Method java/lang/Object."<init>":()V

   
4:   getstatic       #2//Field java/lang/System.out:Ljava/io/PrintStream;

   
7:   ldc     #3//String TT

   
9:   invokevirtual   #4//Method java/io/PrintStream.println:(Ljava/lang/St

ing;)V

   
12:  return

 

static {};

  Code:

   
0:   iconst_5

   
1:   putstatic       #5//Field tt:I

   
4:   return

 

}

 

 

 

 

D:\
>javap -c ArrayTest

Compiled from 
"ArrayTest.java"

public class ArrayTest extends TT{

static int b;

 

int[] A;

 

public ArrayTest();

  Code:

   
0:   aload_0

   
1:   invokespecial   #1//Method TT."<init>":()V

   
4:   aload_0

   
5:   bipush  8

   
7:   newarray int

   
9:   dup

   
10:  iconst_0

   
11:  iconst_1

   
12:  iastore

   
13:  dup

   
14:  iconst_1

   
15:  iconst_4

   
16:  iastore

   
17:  dup

   
18:  iconst_2

   
19:  iconst_5

   
20:  iastore

   
21:  dup

   
22:  iconst_3

   
23:  bipush  12

   
25:  iastore

   
26:  dup

   
27:  iconst_4

   
28:  bipush  34

   
30:  iastore

   
31:  dup

   
32:  iconst_5

   
33:  bipush  123

   
35:  iastore

   
36:  dup

   
37:  bipush  6

   
39:  bipush  14

   
41:  iastore

   
42:  dup

   
43:  bipush  7

   
45:  bipush  32

   
47:  iastore

   
48:  putfield        #2//Field A:[I

   
51:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;

   
54:  ldc     #4//String test

   
56:  invokevirtual   #5//Method java/io/PrintStream.println:(Ljava/lang/St

ing;)V

   
59:  return

 

public static void main(java.lang.String[]);

  Code:

   
0:   new     #6//class ArrayTest

   
3:   dup

   
4:   invokespecial   #7//Method "<init>":()V

   
7:   astore_1

   
8:   iconst_2

   
9:   istore_2

   
10:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;

   
13:  aload_1

   
14:  getfield        #2//Field A:[I

   
17:  iload_2

   
18:  iinc    21

   
21:  iaload

   
22:  invokevirtual   #8//Method java/io/PrintStream.println:(I)V

   
25:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;

   
28:  iload_2

   
29:  invokevirtual   #8//Method java/io/PrintStream.println:(I)V

   
32:  return

 

static {};                                                                                                                

  Code:

   
0:   iconst_5                                                                                                    

   
1:   istore_0

   
2:   iconst_1

   
3:   putstatic       #9//Field b:I

   
6:   bipush  6

   
8:   istore_0

   
9:   return

 

}

 

//第一部分  父类 请先看静态块部分

//代码详解:     --为本人做的注释

D:\
>javap -c TT

Compiled from 
"ArrayTest.java"

class TT extends java.lang.Object{

static int tt;                      --类静态成员变量

 

int t;                                                                                                   --非静态类成员变量

 

public TT();

  Code:

   
0:   aload_0                                                                                                                                                                           --aload_0 装载局部变量0位置对象压入栈顶,注意:aload指令为装类实例,_0表示从局部变量的位置                                                                                            

   
1:   invokespecial   #1//Method java/lang/Object."<init>":()V                                                                                          --invokespecial调用父类方法,使用的是栈顶对象,调用完后栈顶元素出栈,#1表示的是方法名在常量解析池中的位置

   
4:   getstatic       #2//Field java/lang/System.out:Ljava/io/PrintStream;                                                

             
--取得System类的静态成员 ,#2表示常量解析池中的第二个位置

   
7:   ldc     #3//String TT                                                                                 

             
--新建一个String对象指向常量池中的#3,内容是TT,入栈

   
9:   invokevirtual   #4//Method java/io/PrintStream.println:(Ljava/lang/String;)V      

             
--调用类实例方法参数与对象都同时出栈

  
12:  return                                                                                                                                                                            --返回

 

static {};

  Code:

   
0:   iconst_5                                                                                                            

        
--声明一个整形常量为5入栈,iconst_5中的i表示int,当然可以换成f的放就是float型了,const表示常量,5表示数值

   
1:   putstatic       #5//Field tt:I                            

        
--putstatic当栈顶元素出栈放到常量解析池中的#5位置

   
4:   return    

         
--返回

 

}

 

 

 

//第二部分,子类  请先看静态块部分

D:\
>javap -c ArrayTest

Compiled from 
"ArrayTest.java"

public class ArrayTest extends TT{

static int b;

 

int[] A;

 

public ArrayTest();

  Code:

   
0:   aload_0                                                                                                                                                       

               
--将局部变量0位置对象取出来,压入栈push

   
1:   invokespecial   #1//Method TT."<init>":()V                    

              
--调用父类构造方法,并出栈pop

   
4:   aload_0                                                                                                                                                       

              
--将将局部变量0位置对象取出来,压入栈push

   
5:   bipush  8                                                                                                                                             

              
--将(byte)字节8转换成int然后压入栈push

   
7:   newarray int                                                                                                                                  

              
--新建一个数组前面的8 pop出栈,生成的数组对象再压入栈push

   
9:   dup                                                                                                                                                                    

              
--复制当前栈顶对象,再压入栈push  (此时栈里,一个类实例对象,两个数组对象)

   
10:  iconst_0                                                                                                                                            

              
--将整形常量0压入栈(作为数值在数组中的存放位置)push

   
11:  iconst_1                                                                                                                                   

              
--将整形常量1压入栈(作为存入数组中的值)push

   
12:  iastore                                                                                                                                         

              
--数据元素操作指令:在位置上放入刚存入的值pop 1 ;pop 0; pop 数组对象

  
13:  dup                                                                                                                                                                    

           
--再复制数组压入栈,后面的指令与9-12的一样;

   
14:  iconst_1

   
15:  iconst_4

   
16:  iastore

   
17:  dup

   
18:  iconst_2

   
19:  iconst_5

   
20:  iastore

   
21:  dup

   
22:  iconst_3

   
23:  bipush  12

   
25:  iastore

   
26:  dup

   
27:  iconst_4

   
28:  bipush  34

   
30:  iastore

   
31:  dup

   
32:  iconst_5

   
33:  bipush  123

   
35:  iastore

   
36:  dup

   
37:  bipush  6

   
39:  bipush  14

   
41:  iastore

   
42:  dup

   
43:  bipush  7

   
45:  bipush  32

  
47:  iastore                                                                                                                                                                                --此时栈里存放类实例对象,和数组实例对象.

   
48:  putfield        #2//Field A:[I                    

                  
--putfield指把栈顶对象pop,然后赋值给常量解析池中的#2位置          

   
51:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;

                    
--取出静态成员变量push入栈,常量解析池中的#3位置

   
54:  ldc     #4//String test                                       

                  
--新建一个字符串对象test入栈push

   
56:  invokevirtual   #5//Method java/io/PrintStream.println:(Ljava/lang/Sting;)V

                  
--调用类实例方法,方法名在常量解析池中的#5位置,同时pop

   
59:  return


public static void main(java.lang.String[]);

  Code:

   
0:   new     #6//class ArrayTest                                                                                                                                                   --新建一个ArrayTest对象,  名字在常解析池的#6位置,入栈push

   
3:   dup                                                                                      

                     
--复制当前栈顶对象,再压入栈push 

   
4:   invokespecial   #7//Method "<init>":()V                                                                                                                                    --调用父类构造方法pop

   
7:   astore_1                                                                                                                                                                                    --将返回对象放到局部变量位置1,pop

   
8:   iconst_2                                                                                                                                                                                   --新建常量2入栈push

   
9:   istore_2                                                                                                                                                                                    --将栈顶元素保存到局部变量位置2,pop

   
10:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;                            

                     
--取出常量解析池中的#3位置的变量名,取得其静态对象入栈push

   
13:  aload_1                                                                                                                                                                                     --将局部变量中位置1的对象取出入栈push

   
14:  getfield        #2//Field A:[I                                                                                                                                                  --取出其属性#2

   
17:  iload_2                                                                                                                                                                                     --取出局部变量位置2的整型数据入栈

   
18:  iinc    21                                                                                                                                                                             --将栈顶元素自加1再入栈

   
21:  iaload                                                                                                                                                                                      --装栈一个数组的第几个数入栈

   
22:  invokevirtual   #8//Method java/io/PrintStream.println:(I)V                                                                                   

                      
--调用打印方法

   
25:  getstatic       #3//Field java/lang/System.out:Ljava/io/PrintStream;                              

                   
--取出常量解析池中的#3位置的变量名,取得其静态对象入栈push

   
28:  iload_2                                                                                    

                    
--取出局部变量位置2的整型数据入栈

   
29:  invokevirtual   #8//Method java/io/PrintStream.println:(I)V                                                                                   

                    
--调用打印方法

  
32:  return                                                                                                                                                                                          --返回

 

static {};                                                                                               

               
--java虚拟机把所有的静态块以及静态成员都放在一个静态块里执行了,顺序也就是在类里写定义的顺序.

  Code:

   
0:   iconst_5       

              
--声明一个整型5压入栈顶  push

   
1:   istore_0                                                                                      

               
--取出栈顶元素,存到局部变量位置0   pop

   
2:   iconst_1                                                                                          

               
--声明整形变量1压入栈顶  push

   
3:   putstatic       #9//Field b:I 

               
--根据常量解析池位置#9 ,pop 将变量存到位置#9

   
6:   bipush  6                                                                                    

               
--bipush将(byte)字节形转换成(int)整形,并且压入栈push

   
8:   istore_0                                                                                  

               
--取出栈顶元素,存到局部变量位置0   pop  --因为相对于第0和第1名,第6和第8句是在新的静态代码段里面的,所以用的栈也不相同

   
9:   return

 

}

只有注册用户登录后才能发表评论。


网站导航: