class文件是一组以8位字节为基础的二进制流。
ClassFile {
u4 magic; // 魔法数字,表明当前文件是.class文件,固定0xCAFEBABE
u2 minor_version; // 分别为Class文件的副版本和主版本
u2 major_version;
u2 constant_pool_count; // 常量池计数
cp_info constant_pool[constant_pool_count-1]; // 常量池内容
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]; // 各种属性
}
-
魔数与版本
class文件的前四个字节为固定:0xCAFEBABE
紧接着第5、6个字节Minor Version ,第7、8个字节 Major Version -
常量池
常量池里存放两大常量:字面量: 文本字符串、声明为final的常量池
符号引用:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符结构:
常量池入口两字节u2,表示常量池容量计数值;
而接下来就是常量池数组,需要注意的是常量池数组索引为0被保留下来,不位于常量池数组中,而数组的索引从1开始。项目名称:
描述信息: 对于基本数据类型,JVM都用一个大写字母来表示:I - int, C -char, B - byte, D -double, J- long, Z -boolean, S -short, F - float, V - void, L- 对象类型,比如/java/lang/String。 数组类型的话,每一个维度用[ 表示。 -
访问标志
紧跟常量池,2个字节表示访问标志。
-
类索引、父类索引、接口索引集合
类与父类索引是一个u2字类型的索引数据,根据它从常量池中找到
而接口索引集合是一组u2类型的数据的集合,入口第一项为接口计数器(没有实现接口则为0) -
字段表集合
字段表用来描述接口或者类中声明的变量。首先是一个u2类型的fields_count,表示一共有多少个字段。
字段表的结构:
-
方法表集合
方法表的接口与字段表的结构一致。access_flags的值与字段表有差别。 -
属性表集合
属性表定义的结构