CLASS文件结构顺序(无符号字符和表组成):魔数→版本号→常量池→访问标志→类索引→父类索引→接口索引→字段表集合→方法表集合→属性表集合
魔数:
位于Class文件起始4字节:用于进行身份识别,通过虚拟机生成的Class文件魔数为0xCAFEBABE。
版本号:
总共4字节,前两字节表明次版本号,后两字节表明主版本号(即每个JDK大版本),主版本起始值为45(JDK1.1),
每个版本不能向上兼容可以进行向下兼容,兼容后主版本号会根据差值减少。部分示例如下:
jdk
次版本
主版本
JDK1.6.0_01
0x0000
0x0032
JDK1.7.0
0x0000
0x0033
JDK1.8.0
0x0000
0x0034
常量池:
因为常量池中常量(一种表结构)的数量是可变长的,所以前两字节(即9-10字节)表示常量的数量,且为了满足
后面不引用任何常量池的常量的要求,所以常量池容器的计数从1开始,范围是1~(2^64-1)。后面的常量的格
式是标志位(1字节)+数据结构(字节数取决于标志位)。如标志位为0x07,则数据结构为3字节,前一字节是标
志位,后两字节(name_index)表示常量类型索引位置。
各数据类型的结构表:
常量
属性
字节数
描述
CONSTANT_Utf8_info
tag
1
值为1
length
2
UTF-8字符所占据的字节数
bytes
1
长度为前面的length,每个只占1字节
CONSTANT_Integer_info
tag
1
值为3
bytes
4
高位优先存储int值
CONSTANT_Float_info
tag
1
值为4
bytes
4
高位优先存储float值
CONSTANT_Long_info
tag
1
值为5
bytes
8
高位优先存储long值
CONSTANT_Double_info
tag
1
值为6
bytes
8
高位优先存储double值
CONSTANT_Class_info
tag
1
值为7
bytes
2
指向全限定名常量项的索引
CONSTANT_String_info
tag
1
值为8
index
2
指向字符串字面量的索引
CONSTANT_Fieldref_info
tag
1
值为9
index
2
指向CONSTANT_Class_info的索引
index
2
指向CONSTATN_NameAndType_info的索引
CONSTANT_Methodref_info
tag
1
值为10
index
2
指向CONSTANT_Class_info的索引
index
2
指向CONSTATN_NameAndType_info的索引
CONSTANT_InterfaceMethodref_info
tag
1
值为11
index
2
指向CONSTANT_Class_info的索引
index
2
指向CONSTATN_NameAndType_info的索引
CONSTANT_NameAndType_info
tag
1
值为12
index
2
指向该字段或方法名称常量项的索引
index
2
指向该字段或方法描述符常量项的索引
访问标志:
常量池结束后,后面的两个字节表示访问标志(access_flags),用于表明该类或接口的作用域,类型等。比如
public(0x0001)、final(0x0010)等可以通过或运算计算出访问标志的值存入CLASS文件中。
访问标志表:
标志名称
标志值
ACC_PUBLIC
0x0001
ACC_FINAL
0x0010
ACC_SUPER
0x0020
ACC_INTERFACE
0x0200
ACC_ABSTRACT
0x0400
ACC_SYNTHETIC
0x1000
ACC_ANNOTATION
0x2000
ACC_ENUM
0x4000
类索引:
类索引紧随其后占据2字节。类索引通过指向常量池的常量项(CONSTANT_Class_info),用于确定该类的全限定名。
父类索引:
父类索引在类索引之后,占据2字节。父类索引表示该类的继承关系,除了Object是无父类索引(0x0000),
其他均指向常量池的常量项(CONSTANT_Class_info)。
接口索引集合:
接口索引集合在父类索引之后,同样占据2字节。其值表示的是接口数量(n),后面跟着n个2字符指向常量池
(CONSTANT_Class_info)的索引。
字段表集合:
该表结构无固定长度。用于描述类或接口中声明的变量。用于描述名称,类型等。
字段表结构:
名称
类型
数量
描述
access_flag
2字节
1
同上面的访问标志
name_index
2字节
1
指向该字段的简单名称的索引,(即声明的变量名)
descriptor_index
2字节
1
指向描述符的索引(描述符对应见下表)
attributes_count
2字节
1
附加属性的长度
attributes
attribute_info
attributes_count
每个字符占据字节数根据自定义的属性确定,详见属性表
描述符标识字符含义:
标识字符
对应类型
B
byte
C
char
D
double
F
float
I
int
J
long
S
short
Z
boolean
V
void
L
对象类型
( 注:数组类型有特殊方式表示,如String[][]可以用[[Ljava/Lang/String )
方法表集合:
和字段表集合类似,只是在access_flage上有不同。
属性表集合:
属性表没有严格的顺序、长度等,编译器自身定义属性的数据结构。
虚拟机规范预定义的部分属性:
属性名称
使用位置
Code
方法表
ConstatnValue
字段表
Deprecated
类、方法表、字段表
Exceptions
方法表
InnerClasses
类文件
LineNumberTable
Code属性
LocalVariableTable
Code属性
SourceFile
类文件
Synthetic
类、方发表、字段表
(注:JVM1.7规范中定义了21个属性项)
(注:JVM书上的u1、u2、u4、u8等分别表示在class文件中是1字节、2字节、4字节、8字节)