《深入理解Java虚拟机》第三章读书笔记:类文件结构

时间:2022-12-27 20:58:47

1. class文件结构

1、Class文件是一组以8位字节为基础单位的二进制流
2、Class类伪结构有两种数据类型:无符号数和表

  • 无符号数属于基本的数据类型,与u1、u2、u4、u8来分别表示1个字节、2个字节、4个字节和8个字节
  • 表是由多个无符号或其他表作为数据项构成的复合数据类型
类型 名称 数量
u4 magic 1
u2 minor_version 1
u2 major_version 1
u2 constant_pool_count 1
cp_info constant_pool 1
u4 access_flags 1
u4 this_class 1
u4 super_class 1
u4 interfaces_count 1
u4 interfaces 1
u4 fields_count 1
field_info fields 1
u4 methods_count 1
method_info methods 1
u4 attributes_count 1
attributes_info attributes 1

1. 1 魔术与class版本

范例class代码

package Selenium;

public class TestClass {

private int m;

public int inc() {

return m+1;
}

}

《深入理解Java虚拟机》第三章读书笔记:类文件结构

  1. 每个class文件的四个字节表示魔术(0xCAFEBABE)(咖啡宝贝?)
  2. 代表次版本号的第5个和第6个字节值为(0x0000)
  3. 主版本号的值为(0x0033),十进制表示51,51表示是JDK1.7编译的。

1.2 常量池

紧接着主版本号是常量池

《深入理解Java虚拟机》第三章读书笔记:类文件结构
常量池入口第一项为常量池容量计数值(constant_pool_count)(0x0016),十进制表示22,代表有21项常量(从0开始)

常量池之中主要存放两大类常量:字面量和(Literal)
字面量比较接近于java语言层面的常量概念 ,如文本字符串
符号引用用则属于编译原理方面的概念,包括了下面三大常量

  1. 类和接口的全限名称
  2. 字段的名称和描述符
  3. 方法的名称和描述符

常量池中的每一项常量都是一个表。
常量池的项目类型

类型 标志 描述
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_InterfaceMethodref_info 11 接口中的方法的符号引用
CONSTANT_NameAndType_info 12 字段或方法的部分符号引用

《深入理解Java虚拟机》第三章读书笔记:类文件结构

CONSTANT_Class_info型常量结构

类型 名称 数量
u1 tag 1
u2 name_index 1

0x07(十进制:7)表示tag标志,tag标志(7)在常量池的项目类型中指向CONSTANT_Class_info(参考:常量池的项目类型)
《深入理解Java虚拟机》第三章读书笔记:类文件结构
0x02(十进制:2)表示name_index,name_index表示第二项常量。

《深入理解Java虚拟机》第三章读书笔记:类文件结构
第二项常量的tag标志位是0x01(十进制:1),tag标志(1)在常量池的项目类型中指向CONSTANT_Utf8_info(参考:常量池的项目类型)。
CONSTANT_Utf8_info型常量结构

类型 名称 数量
u1 tag 1
u2 length 1
u1 bytes length

0x0012(十进制:12)表示CONSTANT_Utf8_info常量的长度。
53~73字节表示CONSTANT_Utf8_info常量的内容。

1.3 访问标志

在常量池结束之后,紧接着的2个字节代表访问标志(access_flags),这个标志识别一些类或接口层次的访问信息
访问标志列表

标志名称 标志值 含义
ACC_PUBLIC 0X0001 是否为public
ACC_FINAL 0X0010 是否为被声明final,只有类可设置
ACC_SUPER 0X0020 是否允许使用invokespecial字节码指令
ACC_INTERFACE 0X0200 标志这是一个接口
ACC_ABSTRACT 0X0400 是否为abstract类型
ACC_SYNTHETIC 0X1000 标识这个类并非由用户代码产生
ACC_ANNOTATION 0X0001 标识这是一个注解
ACC_ENNUM 0X0001 标识这是一个枚举

总结:太理论了,太枯燥了,看不下去了。