Class文件是一组以8位字节为基本单位的二进制流,二进制的存储格式和虚拟机是实现平台无关性的基石
class文件结构
只有两种数据结构,无符号数 和 表
无符号数是基本的数据类型,以u1,u2,u4,u8,分别表示1字节,2字节,4字节,8字节的无符号数
表是由多个无符号数,或者其他表构成的符合数据结构
class文件格式
类型 | 名称 | 数量 | 描述 |
---|---|---|---|
u4 | magic | 1 | 魔数 |
u2 | minor_version | 1 | 次版本 |
u2 | major_version | 1 | 主版本 |
u2 | constant_pool_count | 1 | 常量池容量 |
cp_info | constant_pool | constant_pool_count -1 | 常量池数据项列表 |
u2 | access_flags | 1 | 访问权限 |
u2 | this_class | 1 | 类全限定名 |
u2 | super_class | 1 | 父类全限定名 |
u2 | interfaces_count | 1 | 接口数量 |
u2 | interfaces | interfaces_count | 接口数据项列表 |
u2 | fiekds_count | 1 | 字段数量 |
field_info | fields | fiekds_count | 字段数据项列表 |
u2 | methods_count | 1 | 方法数量 |
method_info | methods | methods_count | 方法数据项列表 |
u2 | attributes_count | 1 | 属性数量 |
attribute_info | attributes | attributes_count | 属性数据项列表 |
魔数和Class文件的版本
1. class文件的头4个字节称为魔数->0xCAFEBABE
2. 紧接着4位是class文件版本号,5,6字节此版本,7,8字节主版本,版本号从45开始
3. 再接着就是常量池入口,u2类型的常量池容量计数,后面再接着就是数据项
常量池主要存放两大类常量
(1).字面量[文本字符串,声明为final的常量值]
(2).符号引用[包括三大类常量,类和接口的全限定名,字段的名称和描述符,方法的名称和描述符,符号引用需要在运行期动态解析成直接引用,才可被虚拟机使用]
常量池
常量池的项目类型
类型 | 标志 | 描述 |
---|---|---|
CONSTANT_Utf8_info | 1 | UTF-8编码的字符串 |
CONSTANT_Integer_info | 3 | 整型字面量 |
CONSTANT_Float_info | 4 | 浮点型字面量 |
CONSTANT_Long_info | 5 | 长整型字面量 |
CONSTANT_Double_info | 6 | 双精度浮点型字面量 |
CONSTANT_Class_info | 7 | 类或接口的符号引用 |
CONSTANT_String_info | 8 | 字符串类型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符号引用 |
CONSTANT_Methodref_info | 10 | 类中的方法的符号引用 |
CONSTANT_IntefaceMethodref_info | 11 | 接口中的方法的符号引用 |
CONSTANT_NameAndType_info | 12 | 字段和方法的部分符号引用 |
CONSTANT_MethodHandle_info | 15 | 表示方法句柄 |
CONSTANT_MethodType_info | 16 | 标识方法类型 |
CONSTANT_InvokeDynamic_info | 18 | 表示一个动态方法调用点 |
常量池中的14种常量项的结构总表
下面描述的tag值统一都是u1
CONSTANT_Utf8_info
tag:1
length:u2 utf-8编码的字符串占用的字节数【最大 2^16】
bytes:u1,长度为length的utf-8编码的字符串,每个bytes长度为u1,共length个bytes
说明:因为方法名,属性名,接口,类全限定名,都是CONSTANT_Utf8_info类型,
所以CONSTANT_Utf8_info所能表示的最大范围就是支持方法名,属性名,接口,类全限定名的最大范围,所以方法名,属性名,接口,类全限定名不能超过65535个字节的长度,
否则,虚拟机编译会出错,因为常量池CONSTANT_Utf8_info类型装不下
CONSTANT_Integer_info
tag:3
bytes:u4,按照高位在前存储的int值,2^32
CONSTANT_Float_info
tag:4
bytes:u4 按照高位在前存储的float值
CONSTANT_Long_info
tag:5
bytes:u8 按照高位在前存储的long值
CONSTANT_Double_info
tag:6
bytes:u8 按照高位在前存储的double值
CONSTANT_Class_info
tag:7
index: u2 指向全限定名常量项的索引
CONSTANT_String_info
tag:8
index: u2 指向字符串字面量的索引
CONSTANT_Fieldref_info
tag:9
index:u2 指向声明字段的类或接口描述符CONSTANT_Class_info的索引项
index:u2 指向字段描述符CONSTANT_NameAndType_info的索引项
CONSTANT_Methodref_info
tag:10
index:u2 指向声明方法的类描述符CONSTANT_Class_info的索引项
index:u2 指向名称和类型描述符CONSTANT_NameAndType_info的索引项
CONSTANT_IntefaceMethodref_info
tag:11
index:u2 指向声明方法的接口的描述符CONSTANT_Class_info的索引项
index:u2 指向名称和类型描述符CONSTANT_NameAndType_info的索引项
CONSTANT_NameAndType_info
tag:12
index:u2 指向该字段或方法名称常量项的索引
index:u2 指向该字段或方法描述符常量项的索引
CONSTANT_MethodHandle_info
tag:15
reference_kind:u1
reference_index:u2
CONSTANT_MethodType_info
tag:16
descriptor_index:u2
CONSTANT_InvokeDynamic_info
tag:18
bootstap_method_attr_index:u2
name_and_type_index:u2
访问标志
长度 u2