Java类编译后Class文件概述(下)

具体的实例

Java文件

package com.weixuan.test;

public class MyTest {

	private int age;
	private String name;

	public int getAge() {
		return age;
	}

	public String getName() {
		return name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public void setName(String name) {
		this.name = name;
	}

	public static void main(String[] args) {

	}
}

使用javac -g:vars MyTest.java编译,显示localvariable

C:\Users\weixu_000\Desktop>javac -g:vars MyTest.java

C:\Users\weixu_000\Desktop>javap -verbose MyTest.class
Classfile /C:/Users/weixu_000/Desktop/MyTest.class
  Last modified 2015-7-5; size 708 bytes
  MD5 checksum 2d2527c48aba8637fbf99840391879aa
public class com.weixuan.test.MyTest
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #5.#28         // java/lang/Object."<init>":()V
   #2 = Fieldref           #4.#29         // com/weixuan/test/MyTest.age:I
   #3 = Fieldref           #4.#30         // com/weixuan/test/MyTest.name:Ljava/
lang/String;
   #4 = Class              #31            // com/weixuan/test/MyTest
   #5 = Class              #32            // java/lang/Object
   #6 = Utf8               age
   #7 = Utf8               I
   #8 = Utf8               name
   #9 = Utf8               Ljava/lang/String;
  #10 = Utf8               <init>
  #11 = Utf8               ()V
  #12 = Utf8               Code
  #13 = Utf8               LocalVariableTable
  #14 = Utf8               this
  #15 = Utf8               Lcom/weixuan/test/MyTest;
  #16 = Utf8               getAge
  #17 = Utf8               ()I
  #18 = Utf8               getName
  #19 = Utf8               ()Ljava/lang/String;
  #20 = Utf8               setAge
  #21 = Utf8               (I)V
  #22 = Utf8               setName
  #23 = Utf8               (Ljava/lang/String;)V
  #24 = Utf8               main
  #25 = Utf8               ([Ljava/lang/String;)V
  #26 = Utf8               args
  #27 = Utf8               [Ljava/lang/String;
  #28 = NameAndType        #10:#11        // "<init>":()V
  #29 = NameAndType        #6:#7          // age:I
  #30 = NameAndType        #8:#9          // name:Ljava/lang/String;
  #31 = Utf8               com/weixuan/test/MyTest
  #32 = Utf8               java/lang/Object
{
  public com.weixuan.test.MyTest();
    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
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/weixuan/test/MyTest;

  public int getAge();
    descriptor: ()I
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #2                  // Field age:I
         4: ireturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/weixuan/test/MyTest;

  public java.lang.String getName();
    descriptor: ()Ljava/lang/String;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: getfield      #3                  // Field name:Ljava/lang/String;
         4: areturn
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/weixuan/test/MyTest;

  public void setAge(int);
    descriptor: (I)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: iload_1
         2: putfield      #2                  // Field age:I
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/weixuan/test/MyTest;
            0       6     1   age   I

  public void setName(java.lang.String);
    descriptor: (Ljava/lang/String;)V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=2
         0: aload_0
         1: aload_1
         2: putfield      #3                  // Field name:Ljava/lang/String;
         5: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       6     0  this   Lcom/weixuan/test/MyTest;
            0       6     1  name   Ljava/lang/String;

  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=0, locals=1, args_size=1
         0: return
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       1     0  args   [Ljava/lang/String;
}

对应的字节码

cafe babe 0000 0034 001f 0a00 0500 1a09
0004 001b 0900 0400 1c07 001d 0700 1e01
0003 6167 6501 0001 4901 0004 6e61 6d65
0100 124c 6a61 7661 2f6c 616e 672f 5374
7269 6e67 3b01 0006 3c69 6e69 743e 0100
0328 2956 0100 0443 6f64 6501 000f 4c69
6e65 4e75 6d62 6572 5461 626c 6501 0006
6765 7441 6765 0100 0328 2949 0100 0767
6574 4e61 6d65 0100 1428 294c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b01 0006
7365 7441 6765 0100 0428 4929 5601 0007
7365 744e 616d 6501 0015 284c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b29 5601
0004 6d61 696e 0100 1628 5b4c 6a61 7661
2f6c 616e 672f 5374 7269 6e67 3b29 5601
000a 536f 7572 6365 4669 6c65 0100 0b4d
7954 6573 742e 6a61 7661 0c00 0a00 0b0c
0006 0007 0c00 0800 0901 0017 636f 6d2f
7765 6978 7561 6e2f 7465 7374 2f4d 7954
6573 7401 0010 6a61 7661 2f6c 616e 672f
4f62 6a65 6374 0021 0004 0005 0000 0002
0002 0006 0007 0000 0002 0008 0009 0000
0006 0001 000a 000b 0001 000c 0000 001d
0001 0001 0000 0005 2ab7 0001 b100 0000
0100 0d00 0000 0600 0100 0000 0300 0100
0e00 0f00 0100 0c00 0000 1d00 0100 0100
0000 052a b400 02ac 0000 0001 000d 0000
0006 0001 0000 0009 0001 0010 0011 0001
000c 0000 001d 0001 0001 0000 0005 2ab4
0003 b000 0000 0100 0d00 0000 0600 0100
0000 0d00 0100 1200 1300 0100 0c00 0000
2200 0200 0200 0000 062a 1bb5 0002 b100
0000 0100 0d00 0000 0a00 0200 0000 1100
0500 1200 0100 1400 1500 0100 0c00 0000
2200 0200 0200 0000 062a 2bb5 0003 b100
0000 0100 0d00 0000 0a00 0200 0000 1500
0500 1600 0900 1600 1700 0100 0c00 0000
1900 0000 0100 0000 01b1 0000 0001 000d
0000 0006 0001 0000 001a 0001 0018 0000
0002 0019 

具体的解释

1、magic number : 前四个字节 cafe babe,咖啡宝贝

2、次主版本:接下来的四个字节 0000 0034

3、常量池

前两个字节是常量池容量计数器,后面才是常量池

001f : 常量池容量计数器 十进制的31 也就是说,有30个常量,索引是1到30

4、访问标志

常量池结束之后,就是访问标志。

0021 : 只有ACC_PUBLIC和ACC_SUPER为真。即这个类是public 的普通类,无其他修饰符

5、类索引,父类索引与接口索引集合

访问标志之后,就是类索引,父类索引和接口索引集合。

0004 0005 0000
0004:类索引是4,查表, #4 = Class #29 // com/weixuan/test/MyTest
index是29,#29 = Utf8 com/weixuan/test/MyTest	 全类名
0005:父类索引是5,查表, #5 = Class #30 // java/lang/Object
index是30,#30 = Utf8 java/lang/Object 父类是Object
0000:接口信息为0,无接口信息。

6、字段表集合

0002 0002 0006 0007 0000 0002 0008 0009 0000

接口索引集合之后就是字段表的两个字节的字段容量计数器

0002: 2个属性。 在源代码中是,age和name,我们验证一下:

0002 0002 0006 0007
0002:访问标志,查字段访问标志表,0002--->0x0002--->ACC_PRIVATE
0006:name_index,值是6,查表,第一个属性是age
#6 = Utf8 age
0007:第一个属性的描述符索引,值是7,查表,属性类型是I--->int
#7 = Utf8 I
0000:属性信息,无
0002:第二个属性的访问标志,ACC_PRIVATE
0008:name_index,值是8,查表,第二个属性是name
#8 = Utf8 name
0009:描述符索引 值为9,查表,L对象类型,即string 对象类型
#9 = Utf8 Ljava/lang/String;
0000:属性信息,无

7、方法表集合

字段表结束就是方法表集合开头的方法容量计数器,然后是方法表的内容

0006 0001 000a 000b 0001 000c

0006:methods_count 6个方法

源代码中分别是getName(),getAge(),setName(),setAge(),main(),以及编译器添加的<init>方法

0001:访问标志 0001 ---> ACC_PUBLIC,public 
000a:name_index,值为10,查表
#10 = Utf8 <init>
000b:描述符索引,11,查表,方法是 public void()类型,无参
#11 = Utf8 ()V
0001:属性数量 1个
000c:属性索引 值是12 查表,对应的常量是code
#12 = Utf8 Code

8、 编译时,javac -g:vars MyTest.java,可以显示localvariable

分析一下<init>方法的code属性

public com.weixuan.test.MyTest();
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
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this Lcom/weixuan/test/MyTest;

可以看到,statck:1,local:1,codelength:5

找到相应的字节码

0001 0001 0000 0005 2ab7 0001 b1

0001 0001 0000 0005 对应的是stack,local,codelength

2ab7 0001 b1是code的内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值