Java字节码(.class文件)格式详解(一) (一)

2014-11-24 02:33:29 · 作者: · 浏览: 3

小介:去年在读《深入解析JVM》的时候写的,记得当时还想着用自己的代码解析字节码的,最后只完成了一部分。现在都不知道还有没有保留着,貌似Apache有现成的BCEL工程可以做这件事。当时也只是为了学习。这份资料主要参考《深入解析JVM》和《Java虚拟机规范》貌似是1.2版本的,整理出来的。里面包含了一些自己的理解和用实际代码的测试。有兴趣的童鞋可以研究研究。嘿嘿。要有错误也希望能为小弟指点出来,感激不尽。:)

1.总体格式

Class File format

type

descriptor

remark

u4

magic

0xCAFEBABE

u2

minor_version

u2

major_version

u2

constant_pool_count

cp_info

constant_pool[cosntant_pool_count – 1]

index 0 is invalid

u2

access_flags

u2

this_class

u2

super_class

u2

interfaces_count

u2

interfaces[interfaces_count]

u2

fields_count

field_info

fields[fields_count]

u2

methods_count

method_info

methods[methods_count]

u2

attributes_count

attribute_info

attributes[attributes_count]

2. 格式详解

2.1 magic

magic被称为“魔数”,用来标识.class文件的开头。所有合法的.class字节码都应该是该数开头,占4个字节。

2.2 major_version.minor_version

major_version.minor_version合在一起形成当前.class文件的版本号,该版本号一般由编译器产生,并且由sun定义。如59.0。它们一起占4个字节。

2.3 constant_pool

在Java字节码中,有一个常量池,用来存放不同类型的常量。由于Java设计的目的之一就是字节码需要经网络传输的,因而字节码需要比较紧凑,以减少网络传输的流量和时间。常量池的存在则可以让一些相同类型的值通过索引的方式从常量池中找到,而不是在不同地方有不同拷贝,缩减了字节码的大小。

每个常量池中的项是通过cp_info的类型来表示的,它的格式如下:

cp_info format

type

descriptor

remark

u1

tag

u1

info[]

这里tag用来表示当前常量池不同类型的项。info中存放常量池项中存放的数据。

tag中表示的数据类型:

CONSTANT_Class_info (7)、

CONSTANT_Integer_info (3)、

CONSTANT_Long_info (5)、

CONSTANT_Float_info (4)、

CONSTANT_Double_info (6)、

CONSTANT_String_info (8)、

CONSTANT_Fieldref_info (9)、

CONSTANT_Methodref_info (10)、

CONSTANT_InterfaceMethodref_info (11)、

CONSTANT_NameAndType_info (12)、

CONSTANT_Utf8_info (1)、

注:在Java字节码中,所有boolean、byte、char、short类型都是用int类型存放,因而在常量池中没有和它们对应的项。

2.3.1 CONSTANT_Class_info

用于记录类或接口名(used to represent a class or an interface)

CONSTANT_Class_info format

type

descriptor

remark

u1

tag

CONSTANT_Class (7)

u2

name_index

constant_pool中的索引,CONSTANT_Utf8_info类型。表示类或接口名。

注:在Java字节码中,类和接口名不同于源码中的名字,详见附件A.

2.3.2 CONSTANT_Integer_info

用于记录int类型的常量值(represent 4-byte numeric (int) constants:)

CONSTANT_Integer_info

type

descriptor

remark

u1

tag

CONSTANT_Integer (3)

u4

bytes

整型常量值

2.3.3 CONSTANT_Long_info

用于记录long类型的常量值(represent 8-byte numeric (long) constants:)

CONSTANT_Long_info

type

descriptor

remark

u1

tag

CONSTANT_Long (5)

u4

high_bytes

长整型的高四位值

u4

low_bytes

长整型的低四位值

2.3.4 CONSTANT_Float_info

用于记录float类型的常量值(represent 4-byte numeric (float) constants:)

CONSTANT_Float_info

type

descriptor

remark

u1

tag

CONSTANT_Float(4)

u4

bytes

单精度浮点型常量值

几个特殊值:0x7f800000 => Float.POSITIVE_INFINITY、0xff800000 => Float.NEGATIVE_INFINITY、

0x7f800001 to 0x7fffffff => Float.NaN、0xff800001 to 0xffffffff => Float.NaN

2.3.5 CONSTANT_Double_info

用于记录double类型的常量值(represent 8-byte numeric (double) constants:)

CONSTANT_Do