常量池是 Class 文件的「資源倉庫」,11 種數據項類型中,CONSTANT_Utf8_info 與 CONSTANT_NameAndType_info 是最基礎的兩種——其他 9 種數據項直接或間接引用它們。本文按依賴順序,優先深度解析這兩大核心數據項的存儲格式、引用關係與實際編碼案例。

存儲內容涵蓋 5 大類:
"Hello")Code、LineNumberTable、SourceFile 等屬性名)#2 = Utf8 com/jg/zhang/Programer // 當前類名 #4 = Utf8 com/jg/zhang/Person // 父類名 #5 = Utf8 company // 字段名 #6 = Utf8 Ljava/lang/String; // 字段描述符 #7 = Utf8 position // 字段名 #8 = Utf8 computer // 字段名 #9 = Utf8 Lcom/jg/zhang/Computer; // 字段描述符 #10 = Utf8 <clinit> // 靜態初始化方法名 #11 = Utf8 ()V // 方法描述符 #12 = Utf8 Code // 屬性名 #14 = Utf8 CompanyA // 字符串常量 #19 = Utf8 java/lang/System // 引用類名 #21 = Utf8 out // 引用字段名 #22 = Utf8 Ljava/io/PrintStream; // 引用字段描述符 #24 = Utf8 staitc init // 字符串常量(含拼寫錯誤) #27 = Utf8 java/io/PrintStream // 引用類名 #29 = Utf8 println // 引用方法名 #30 = Utf8 (Ljava/lang/String;)V // 引用方法描述符 #31 = Utf8 LineNumberTable // 屬性名 #32 = Utf8 LocalVariableTable // 屬性名 #33 = Utf8 <init> // 構造方法名 #41 = Utf8 com/jg/zhang/Computer // 引用類名 #45 = Utf8 this // 局部變量名 #46 = Utf8 Lcom/jg/zhang/Programer; // 局部變量描述符 #47 = Utf8 working // 方法名 #49 = Utf8 coding... // 字符串常量 #52 = Utf8 SourceFile // 屬性名 #53 = Utf8 Programer.java // 源文件名

CONSTANT_Utf8_info(字段/方法名)CONSTANT_Utf8_info(描述符)// Person.java
public class Person {
int age;
int getAge() { return age; } // 訪問 age 字段
}
反編譯常量池關鍵項:
#5 = Utf8 age #6 = Utf8 I #16 = Utf8 getAge #17 = Utf8 ()I #18 = Fieldref #1.#19 // Person.age:I #19 = NameAndType #5:#6 // age:I #20 = Methodref #3.#11 // Object."<init>":()V #11 = NameAndType #7:#8 // "<init>":()V
age 字段在 getAge() 中被讀取 → 生成 NameAndType #19getAge()、<init>() 未被外部調用 → 不生成 對應 NameAndTypesuper() → 生成父類構造器的 NameAndType #11



| Java 類型 | 描述符 |
|---|---|
| byte/short/char/boolean/int | B/S/C/Z/I |
| long | J |
| float/double | F/D |
| 引用類型 | L全限定名; |
| 數組 | [描述符 |
| 方法 | (參數描述符)返回描述符 |
CONSTANT_Utf8_info 存儲所有可見字符串,CONSTANT_NameAndType_info 組合「名稱+描述符」形成字段/方法的符號引用標識。其他引用類數據項(Fieldref、Methodref、InterfaceMethodref)進一步包裝「類引用+NameAndType」,構成完整符號引用鏈。這種分層引用設計,極大減少了字符串重複存儲,體現了 Class 文件緊湊高效的工程智慧。