书接上文虚拟机(四)
接着说Class文件结构,前文说完了常量池的结构,紧跟着是访问标记。
访问标记
2字节表示,用于表明该类的访问信息,如public、final、abstract等。
每种类型的表示都是通过设置访问标记32位中的特定位来实现。
标记名称 | 数值 | 描述 |
---|---|---|
ACC_PUBLIC | 0x0001 | 表示public |
ACC_FINAL | 0x0010 | 是否为final类 |
ACC_SUPER | 0x0020 | 使用增强的方法调用父类方法 |
ACC_INTERFACE | 0x0200 | 是否为接口 |
ACC_ABSTRACT | 0x0400 | 是否为抽象类 |
ACC_SYNTHETIC | 0x1000 | 由编译器产生的类,无源码对应 |
ACC_ANNOTATION | 0x2000 | 是否是注释 |
ACC_ENUM | 0x4000 | 是否是枚举 |
使用ACC_SUPER可以让类更准确的定位到父类的方法 super.method()。
当前类、父类和接口
访问标记后,会指定该类的类别、父类类别及实现的接口:
this_class (2字节无符号整数,指向常量池中一个CONSTANT_Class)
super_class (2字节无符号整数,指向常量池中一个CONSTANT_Class)
interfaces_count
interfaces[interfaces_count] (每个索引指向常量池中一个CONSTANT_Class)
Class文件的字段
接口描述后,会有类的字段信息,首先指明字段的个数。
u2 fields_count;
field_info fields[fields_count];
field_info的结构:
field_info {
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
结构中:
- 字段的访问标记,类似类的访问标记,没有super、接口、注释、抽象标记,新增如下
标记名称 | 数值 | 描述 |
---|---|---|
ACC_PRIVATE | 0x0002 | 表示private |
ACC_PROTECTED | 0x0004 | 表示protected |
ACC_STATIC | 0x0008 | 表示静态字段 |
ACC_VOLATILE | 0x0040 | 是否为volatile |
ACC_TRANSIENT | 0x0080 | 是否为瞬时字段,表示在持久化读写时忽略该字段 |
- 一个2字节整数,表示字段的名称,指向常量池中CONSTANT_Utf8结构
- descriptor_index指向常量池中CONSTANT_Utf8,描述字段的类型。
- 字段还可能拥有一些属性,用于存储更多的额外信息,比如初始化值、注释信息等。属性个数存放在count中,具体内容放在attributes数组中。
Class文件的方法基本结构
字段后是类的方法信息,由两部分组成:
u2 methods_count;
method_info methods[methods_count];
methods_count是2字节整数,表示类中有几个方法。接着是count个info结构,结构如下:
method_info{
u2 access_flags;
u2 name_index;
u2 descriptor_index;
u2 attributes_count;
attribute_info attributes[attributes_count];
}
结构中:
- 访问标记,表明方法的权限和相关特性
- 方法的名称
- 方法描述符,表示方法的签名
- 描述额外信息,方法字节码等。