Chinaunix首页 | 论坛 | 博客
  • 博客访问: 107543
  • 博文数量: 14
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 184
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-01 23:15
个人简介

我只是一个喜欢开发的测试,喜欢测试的开发,喜欢每天都知道得更多一些,更深入一些的感觉。。。。。

文章分类

全部博文(14)

文章存档

2015年(5)

2014年(2)

2013年(7)

分类: Java

2013-08-30 08:17:50

4.    访问标志(access_flags)

访问标志在紧接着常量表后面的两个字节,本例中常量表的最后一个字节偏移量是0x0000028d,因此0x0000 028e、0x0000 028f两个字节即访问标志。

0x0021(0x0001 | 0x0020),即ACC_PUBLICACC_SUPER标志为真。



5.    索引(this_class , super_class & interfaces)


访问标志后的两个字节是类索引,0x0001表示指向常量表的第一个表项,查之前我们整理的常量表各表项解析结果可知,该表项为一个CONSTANT_Class_info类型的表项,其全限定名为“com/momo/javatips/jmx/HelloWorld”。


接着的两个字节是父类索引,0x0003,常量表的第三个表项,全限定名“java/lang/Object”。


接口索引部分,因为Java运行一个类实现多个接口,因此可能存在多个接口索引,所以这部分是一个表格,头两个字节是表格长度,说明有几个接口,在此0x0001HelloWorld实现了一个接口,这个接口的索引是0x0005,常量表的第五个表项,全限定名“com/momo/javatips/jmx/HelloWorldMBean”。

可以看出这三个索引是为了说明类的继承关系的,本类继承自哪个父类,又实现了哪些接口。



6.    字段表(fields)

字段表,显然是用来说明类中的成员字段的,包括静态的和非静态的。



上图是本例中的字段表部分,首先是字段表长度0x0001,只有一个字段,接着是各字段的具体信息:

偏移量

信息项 

信息值

分析结果

0000 029a

访问标志

0x0002

ACC_PRIVATE,为private字段

0000 029c

字段名索引

0x0007

指向常量表第7个字符串表项,值为name

0000 029e

描述符索引

0x0008

指向常量表第8个字符串表项,值为Ljava/lang/String;

0000 02a0

属性表长度

0x0000

无属性


而代码中确实只有一个String类型的private字段name



7.    方法表(methods)

方法表起始两个字节为方法表长度,0x0005即有5个方法,让我们来逐个解析。


1)     ()V


 

偏移量

信息项

信息值

分析结果

0000 02a4

访问标志

0x0001

ACC_PUBLIC,为public方法

0000 02a6 

方法名索引 

0x0009 

指向常量表第9个字符串表项,值为

0000 02a8 

描述符索引 

0x000A 

指向常量表第10个字符串表项,值为()V 

0000 02aa 

属性表长度 

0x0001 

一个属性 

0000 02ac

Code
属性


 

属性名索引

0x000B

指向常量表第11个字符串表项,值为Code

0000 02ae 

属性长度 

0x0000002F

47字节

0000 02b2

max_stack

0x0001

操作数栈在运行执行的任何时间点的最大深度为1

0000 02b4

max_locals

0x0001

1个局部变量

0000 02b6

code_length

0x00000005

方法代码编译后的字节码5个字节

0000 02ba

code[]

0x2AB7000CB1

0000 02bf

异常处理表长度

0x0000

无异常处理

0000 02c1

属性表长

0x0002

2属性

0000 02c3

属性1


 

属性名索引

0x000E

指向常量表第14个字符串表项,值为LineNumberTable

0000 02c5

属性长度

0x00000006

6字节

0000 02c9

属性值

0x00 01……00 04

0000 02cf

属性2


 

属性名索引

0x000F

指向常量表第15个字符串表项,值为LocalVariableTable

0000 02d1

属性长度

0x0000000C

12字节

0000 02d5

属性值

0x00 01……00 00



2)   public java.lang.String getName();


 

偏移量

信息项

信息值

分析结果

0000 02e1

访问标志

0x0001

ACC_PUBLIC,为public方法

0000 02e3

方法名索引

0x0012 

指向常量表第18个字符串表项,值为getName

0000 02e5

描述符索引

0x0013

指向常量表第19个字符串表项,值为()Ljava/lang/String;

0000 02e7

属性表长度

0x0001

一个属性

0000 02e9

Code
属性


 

属性名索引

0x000B

指向常量表第11个字符串表项,值为Code

0000 02eb

属性长度

0x0000002F

47字节

0000 02ef

max_stack

0x0001

操作数栈在运行执行的任何时间点的最大深度为1

0000 02f1

max_locals

0x0001 

1个局部变量

0000 02f3

code_length

0x00000005

方法代码编译后的字节码5个字节

0000 02f7

code[]

0x2AB40014B0

0000 02fc

异常处理表长度

0x0000

无异常处理

0000 02fe

属性表长

0x0002

2属性

0000 0300

属性1


 

属性名索引

0x000E

指向常量表第14个字符串表项,值为LineNumberTable

0000 0302

属性长度

0x00000006

6字节

0000 0306

属性值

0x00 01……00 08

0000 030c

属性2


 

属性名索引

0x000F

指向常量表第15个字符串表项,值为LocalVariableTable

0000 030e

属性长度

0x0000000C

12字节

0000 0312

属性值

0x00 01……00 00


 

3)   public void setName(java.lang.String);

  

偏移量

信息项

信息值

分析结果

0000 031e

访问标志

0x0001

ACC_PUBLIC,为public方法

0000 0320

方法名索引

0x0016

指向常量表第22个字符串表项,值为setName

0000 0322

描述符索引

0x0017

指向常量表第23个字符串表项,值为(Ljava/lang/String;)V

0000 0324

属性表长度

0x0001

一个属性

0000 0326

Code
属性


 

属性名索引 

0x000B 

指向常量表第11个字符串表项,值为Code

0000 0328

属性长度

0x0000003E

62字节

0000 032c

max_stack

0x0002

操作数栈在运行执行的任何时间点的最大深度为2

0000 032e

max_locals

0x0002

2个局部变量t

0000 0330 

code_length

0x00000006

方法代码编译后的字节码6个字节

0000 0334

code[]

0x2A2BB50014B1

0000 033a

异常处理表长度

0x0000

无异常处理

0000 033c

属性表长

0x0002

2属性

0000 033e

属性1


 

属性名索引

0x000E

指向常量表第14个字符串表项,值为LineNumberTable

0000 0340 

属性长度

0x0000000A

10字节

0000 0344

属性值

0x00 02……00 0D

0000 034e

属性2


 

属性名索引

0x000F

指向常量表第15个字符串表项,值为LocalVariableTable

0000 0350

属性长度

0x00000016

22字节

0000 0354

属性值

0x00 02……00 01


 

4)    public void printHello();



偏移量

信息项

信息值

分析结果

0000 036a

访问标志

0x0001

ACC_PUBLIC,为public方法

0000 036c

方法名索引

0x0018

指向常量表第24个字符串表项,值为printHello

0000 036e

描述符索引

0x000A

指向常量表第10个字符串表项,值为(Ljava/lang/String;)V

0000 0370

属性表长度

0x0001

一个属性

0000 0372

Code
属性


 

属性名索引

0x000B

指向常量表第11个字符串表项,值为Code

0000 0374

属性长度

0x00000048

72字节

0000 0378

max_stack

0x0004

操作数栈在运行执行的任何时间点的最大深度为4

0000 037a

max_locals

0x0001

1个局部变量

0000 037c

code_length

0x0000001A

方法代码编译后的字节码26个字节

0000 0380

code[]

0xB2 00……2C B1

0000 039a

异常处理表长度

0x0000

无异常处理

0000 039c

属性表长

0x0002

2属性

0000 039e

属性1


 

属性名索引

0x000E

指向常量表第14个字符串表项,值为LineNumberTable

0000 03a0

属性长度

0x0000000A

10字节

0000 03a4

属性值

0x00 02……00 11

0000 03ae

属性2


 

属性名索引

0x000F

指向常量表第15个字符串表项,值为LocalVariableTable

0000 03b0

属性长度

0x0000000C

12字节

0000 03b4

属性值

0x00 01……00 00



5)    public void printHello(java.lang.String);



偏移量

信息项

信息值

分析结果

0000 03c0

访问标志

0x0001

ACC_PUBLIC,为public方法

0000 03c2

方法名索引

0x0018

指向常量表第24个字符串表项,值为printHello

0000 03c4

描述符索引

0x0017

指向常量表第23个字符串表项,值为(Ljava/lang/String;)V

0000 03c6

属性表长度

0x0001

一个属性

0000 03c8

Code
属性


 

属性名索引

0x000B

指向常量表第11个字符串表项,值为Code

0000 03ca

属性长度

0x0000004F

79字节

0000 03ce

max_stack

0x0004

操作数栈在运行执行的任何时间点的最大深度为4

0000 03d0

max_locals

0x0002

2个局部变量

0000 03d2

code_length

0x00000017

方法代码编译后的字节码23个字节

0000 03d6

code[]

0xB2 00……B1 00

 

0000 03ed

异常处理表长度

0x0000

无异常处理

0000 03ef

属性表长

0x0002

2属性

0000 03f1

属性1


 

属性名索引

0x000E

指向常量表第14个字符串表项,值为LineNumberTable

0000 03f3

属性长度

0x0000000A

10字节

0000 03f7

属性值

0x00 02……00 15

0000 0401

属性2


 

属性名索引

0x000F

指向常量表第15个字符串表项,值为LocalVariableTable

0000 0403

属性长度

0x00000016

22字节

0000 0407

属性值

0x00 02……00 01



8.    属性表(attributes)

属性表开始2个字节的值0x0001说明只有一个属性,接着是这个属性的名称在常量表中的索引0x0034,指向第52个表项,值为“SourceFile”;0x00000002属性长度为两个字节;0x0035,指向第53个表项,值为“HelloWorld.java”,即这个属性说明了这个class的源文件是HelloWorld.java



小结

本文中,我们只是粗浅地将一个简单的class文件的各个部分过了一遍,并没有进一步去挖掘更多更深一些的内涵,把各个部分串起来,用JDK自身提供的工具Javap –verbose选项可以看到更多的信息,但我希望能自己摸索一下以便对class文件结构有更多的理解,让我们在后续慢慢深入吧,这一篇就先到这儿。



参考文献

1.    《深入理解Java虚拟机:JVM高级特性与最佳实践》 周志明 著,机械工业出版社,2011

2.    Java虚拟机规范(Java SE 7)Tim LindholmFrank YellinGilad BrachaAlex Buckley 著,周志明,吴璞渊,冶秀刚
译,2011

3.     《深入java虚拟机(第二版) []Bill Venners 著, 曹晓钢,蒋靖 译,机械工业出版社,2003

4.    



阅读(1859) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~