2 Class文件结构

2.1. Class文件的组成

组成部分 功能
Magic Number 文件标识符
Minor version Jdk的版本号中的小版本号
Major version Jdk版本号中的大版号
constant_pool_count 常量池中常量的数量
constant_pool 常量池的具体实现,常量池中具体有什么内容
access_flags 整个class文件的修饰符
this_class 当前类的名称
super_class 当前类的父类名称
interfaces_count 实现接口的数量
Interfaces 具体实现了哪些接口
Fields_count 属性的数量
fields 具体有哪些属性
Methods_count 具有方法的数量
methods 具体具有哪些方法
Attributes_count – u2 附加属性的数量
attributes 具体有哪些附加属性

2.2. Magic Number、Minor Number、Major Number

字节码文件如下所示,其中前四位字节码标识是Magic Number。例如这里的CA FE BA BE,表示该字节码文件是java编译后的class文件。
第五位和第六位表示JDK版本号的小版本,即Minor Number,第七位和第八位表示JDK版本号的小版本,即Major Number。例如这里采用JDK1.8,所以Major Number为00 34,因为JDK1.8在所有JDK中序号为52,JDK1.7为51;这里使用的又是JDK1.8中的第一个版本,所以为JDK1.8.0,所以这里的Minor Number为00 00。
虚拟机基础概念-Class文件结构

2.3. constant_pool_count、constant_pool

constant_pool_count表示常量池中常量的数量,但是该数需减去一,因为第0位不存储任何常量,作为一个备用位置,当不使用常量池中任何常量时指向该位置。例如,图中00 10就表示常量池中常量的数量为16-1=15个。constant_pool_count占用了四个16进制位,又因为第0位不存储任何常量,所以constant_pool_count的最大值为216-1-1 = 65536 -2 = 65534,即最多可以存放65534个常量。
constant_pool表示常量池中具体的内容了,所占地址位数不限。
常量池的常量类型分类,共有14种,具体如下:
tag 名称 length Bytes
1 CONSTANT_Uft8_info UTF-8字符串占用的长度 长度位length的字符串
3 CONSTANT_Integer_info 4字节 Big-Dndian(高位在前)存储的int值
4 CONSTANT_Float_info 4字节 Big-Dndian(高位在前)存储的float值
5 CONSTANT_Long_info 8字节 Big-Dndian(高位在前)存储的long值
6 CONSTANT_Double_info 8字节 Big-Dndian(高位在前)存储的double值
7 CONSTANT_Class_info 2字节 指向类的全限定名项的索引
8 CONSTANT_String_info 2字节 指向字符串字面量的索引
9 CONSTANT_Fieldref_info 2字节 指向声明字段的类或接口描述符CONSTANT_Class_info的索引项
2字节 指向字段描述符CONSTANT_NameAndType的索引项
10 CONSTANT_Methodref_info 2字节 指向声明字段的类或接口描述符CONSTANT_Class_info的索引项
2字节 指向字段描述符CONSTANT_NameAndType的索引项
11 CONSTANT_interfaceMethodref_info 2字节 指向声明字段的类或接口描述符CONSTANT_Class_info的索引项或指向字段描述符CONSTANT_NameAndType的索引项
2字节 指向字段描述符CONSTANT_NameAndType的索引项
12 CONSTANT_NameAndType_info 2字节 指向该字段或方法名称常量项的索引
2字节 指向该字段方法描述符常量项的索引
15 CONSTANT_MethodHandle_info 1字节 reference_kind:1-9之间的一个值,决定了方法句柄的类型,方法句柄类型的值表示方法句柄的字节码行为
2字节 Reference_index:对常量池的有效索引
16 CONSTANT_MethodType_info 2字节 Descriptor_index:指向UTF8-info结构表示的方法描述符
18 CONSTANT_InvokeDynamic_info 2字节 Bootstrap_method_attr_index:当前class文件引导方法表的bootstrap_methods[]数组的有效索引
2字节 Name_and_type_index:指向NameAndType_info表示的方法名和方法描述符
Constant_pool常量池的应用举例:如下图为常量池中的内容,在常量池中的1号位置处,数据类型为CONSTANT_Methodref_info,该数据类型共存储4个字节内容,其中前两个字节为指向声明字段的类(存储在常量池中的第三号位置),后两个字节为指向指向字段描述符CONSTANT_NameAndType的索引项(存储在常量池的第13号位置处)。上述介绍表现在字节码文件中,如字节码图中的绿色位置所示。
虚拟机基础概念-Class文件结构
虚拟机基础概念-Class文件结构

2.4. access flags

该class文件的修饰符,例如public、final等,这些不是单选的,可以是拥有多个类型,多个类型最终是叠加到一起,用一个十六进制数值表示的所有的。
虚拟机基础概念-Class文件结构

2.5. this_class、super_class

this_class表示当前类,存储的是当前类在常量池中类的全限定名项索引的位置;super_class表示当前类的父类,存储的是当前类的父类在常量池中类的全限定名项索引的位置。
例如这里this_class存储的cp_info #2表示当前类存储在常量池中的二号位置,而类的名称存储在cp_info #14位置处,其具体名称为“<src/Test/test>”。这里面就存在常量池中各变量的互相引用。
虚拟机基础概念-Class文件结构

2.6. Fields

1)Fields属性中存储的内容
虚拟机基础概念-Class文件结构

其中,access_flags表示属性的类型,例如有public、private、volatile等;name_index表示属性的名称,该名称放在常量池中;descriptor_index表示数据类型,例如int、flaot、long等,不过是该类型相对应的缩写;attributes_count表示附加属性的数量,attributes表示附加属性具体有哪些。
2)Access_flags表示的属性类型具体有:
虚拟机基础概念-Class文件结构

3)descriptor_index表示数据类型具体有:
虚拟机基础概念-Class文件结构

2.7. Methods

1) Methods中的内容
虚拟机基础概念-Class文件结构

其中,access_flags表示该方法的修饰符,例如有public、private、volatile等;name_index表示方法的名称,该名称放在常量池中;descriptor_index表示方法的传入形式,例如void a()、int a()、int a(int para1, int[] para2)等,不过是这些类型的缩写形式;attributes_count表示附加属性的数量,attributes表示附加属性具体有哪些。
注意事项:
Method中有类默认的构造方法,而且在该构造方法中会实现父类中的构造方法(无参构造方法)

相关文章: