# 字节码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的常量值等。
符号引用主要包括以下几类:
- 被模块导出或开放的包
- 类和接口的全限定名
- 字段的名称和描述符
- 方法的名称和描述符
- 方法句柄和方法类型
- 动态调用点和动态常量
当JVM做类加载时,会从常量池中获取符号引用,再在类创建或运行时去解析、翻译到具体的内存地址之中。
常量池中每一项常量都是一个表,共有17种类型,表结构的第一位用u1类型的标志位代表当前属于哪种常量类型。

# 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 |