首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Class 文件常量池深度解析:CONSTANT_Utf8 與 CONSTANT_NameAndType 結構詳解

     編輯:Java 相關知識

Java Class 文件常量池核心數據項:Utf8 與 NameAndType 結構完整剖析

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

CONSTANT_Utf8_info:字符串常量存儲基石

Utf8_info結構圖

  • tag = 1(1 字節)
  • length:字符串字節長度(2 字節,大端序)
  • bytes[]:Modified UTF-8 編碼的字符串內容

存儲內容涵蓋 5 大類:

  1. 程序字符串字面量(如 "Hello")
  2. 類/接口/枚舉完全限定名(本類、父類、實現接口、引用類)
  3. 字段/方法名稱
  4. 字段/方法描述符
  5. 屬性相關字符串(如 Code、LineNumberTable、SourceFile 等屬性名)

實戰案例:Programer 類常量池 Utf8 項完整清單

#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_NameAndType_info:字段/方法符號引用核心

NameAndType_info結構圖

  • tag = 12
  • name_index:指向 CONSTANT_Utf8_info(字段/方法名)
  • descriptor_index:指向 CONSTANT_Utf8_info(描述符)
  • 一個 NameAndType 項 = 一個字段或方法的符號引用標識

關鍵機制:只有被引用才生成 NameAndType

// 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 #19
  • getAge()、<init>() 未被外部調用 → 不生成 對應 NameAndType
  • 子類構造器隱式調用 super() → 生成父類構造器的 NameAndType #11

NameAndType引用關係圖

字段NameAndType示意圖

構造器NameAndType內存佈局

字段NameAndType內存佈局

描述符編碼規則速查

Java 類型描述符
byte/short/char/boolean/intB/S/C/Z/I
longJ
float/doubleF/D
引用類型L全限定名;
數組[描述符
方法(參數描述符)返回描述符

總結

CONSTANT_Utf8_info 存儲所有可見字符串,CONSTANT_NameAndType_info 組合「名稱+描述符」形成字段/方法的符號引用標識。其他引用類數據項(Fieldref、Methodref、InterfaceMethodref)進一步包裝「類引用+NameAndType」,構成完整符號引用鏈。這種分層引用設計,極大減少了字符串重複存儲,體現了 Class 文件緊湊高效的工程智慧。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved