# 字节码Class文件

# Class文件结构

任何一个class文件都对应着唯一的一个类或接口的定义信息。

class文件不需要以磁盘文件的形式存在,可以动态生成,也可以通过网络传输到类加载器种。

Java字节码是由单字节的指令组成的,也就是一个byte(8bit)组成,所以理论上最多只能有256(2^8)个指令操作码(opcode)。实际上到目前为止,Java规范里只使用了200个左右的操作码,
字节码文件是十六进制文件,可以使用nodepad++打开即可。

Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在文件中,中间没有添加任何分隔符。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前(BE)的方式分割成若干个8个字节进行存储。

# 常量池

Class文件的资源仓库。

在Class文件中,紧随主、次版本号之后。其中常量数量不固定,所以在常量池入口放置一个u2类型的数据表示常量池容量计数值(Constant_pool_count),从1开始计数。若某些场景下需要表示“不引用任何一个常量池项目”则计数值使用0。

常量池主要存放两大类:字面量(Literal)、符号引用(Symbolic References)。

字面量:通常意义的常量,例如文本字符串、被声明为final的常量值等。

符号引用主要包括以下几类:

  1. 被模块导出或开放的包
  2. 类和接口的全限定名
  3. 字段的名称和描述符
  4. 方法的名称和描述符
  5. 方法句柄和方法类型
  6. 动态调用点和动态常量

当JVM做类加载时,会从常量池中获取符号引用,再在类创建或运行时去解析、翻译到具体的内存地址之中。

常量池中每一项常量都是一个表,共有17种类型,表结构的第一位用u1类型的标志位代表当前属于哪种常量类型。

image-20220514214252010

# CONSTANT_Class_info

代表一个类或者接口的符号引用

类型 名称 数量
u1 tag(标志位,用于区分常量类型) 1
u2 name_index(常量池的索引值,指向一个CONSTANT_Utf8_info类型常量,代表类的全限定名) 1

# CONSTANT_Utf8_info

类型 名称 数量
u1 tag 1
u2 length(表示UTF-8编码的字符串长度是多少字节) 1
u1 bytes length
修改于: 8/11/2022, 3:17:56 PM