JVM-class文件完全解析-常量池


  在.java文件,講過javac編譯后產生的 .class文件中,頭4個字節表示的是魔數,接着魔數后面的第5,6個字節存儲的是次版本號,第7,8個字節存儲的主板本號.那么再接下來的就是表示常量池入口了. 

常量池 

  可以理解為class文件之中的資源倉庫,它是class文件結構中與其他項目關聯最多的數據類型,也是占用class文件空間最大的數據項目之一,同時它還是class文件中第一個出現表類型的數據項目.

   由於常量池的數量是不固定的,所以在常量池入口需要放置一項u2(即2個字節)類型的數據,代表常量池容量計數值(constant-pool-count)(從1開始,將0表示不引用任何常量).

  常量池中主要存放兩大類常量:字面量(Literal)和符號引用(Synbolic Reference).

  • 字面量:比較接近於Java語言層面的常量概念,如文本字符串,聲明為final的常量值.
  • 符號引用:包括如下三類常量:
  1. 類和接口的全限定名(Fully Qualified Name)
  2. 字段的名稱和描述符(Descriptor)
  3. 方法的名稱和描述符 

常量池中每一項常量都是一個表(14種表). 

類型 標志 描述 
CONSTANT_utf8_info 1  UTF-8編碼的字符串
CONSTANT_Integer_info 3 整形字面量
CONSTANT_Float_info 4 浮點型字面量
CONSTANT_Long_info 長整型字面量
CONSTANT_Double_info 雙精度浮點型字面量
CONSTANT_Class_info 類或接口的符號引用
CONSTANT_String_info 字符串類型字面量
CONSTANT_Fieldref_info 字段的符號引用
CONSTANT_Methodref_info 10 類中方法的符號引用
CONSTANT_InterfaceMethodref_info 11 接口中方法的符號引用
CONSTANT_NameAndType_info 12 字段或方法的符號引用
CONSTANT_MothodType_info 16 標志方法類型
CONSTANT_MethodHandle_info 15 表示方法句柄
CONSTANT_InvokeDynamic_info 18 表示一個動態方法調用點

  注意:在這14種表有一個共同的特點,就是開始的第一位是一個u1類型的標志位(tag,就是上表中的標志這一列),代表當前這個常量屬於哪種常量類型.下面分析實例的時候會用到.

    由於class文件中方法,字段等都需要引用CONSTANT_utf8_info類型常量來描述名稱,所以CONSTANT_utf8_info類型常量的最大長度也就是Java中方法,字段名的最大長度(Java程序中如果定義了超過64KB英文字符的變量或方法名,將無法編譯).

下面我們接着上一篇分析的class文件繼續往下走.

   這張圖中,我們繼續分析了接着主版本號接下來的幾個字節,首先是常量池入口是0x0013,轉化為十進制就是19,那么表示的范圍就是1~18,因為0用來表示不引用任何常量池了.那么也就是說0x0013之后有18個常量池.我們看緊接着的一個常量池,十六進制0x0a用十進制表示就是10,通過上表的標志列我們可以直到,10對應的那一行就是CONSTANT_Methodref_info類型的表,是類中方法的符號引用.那么知道了是CONSTANT_Methodref_info表,就可以根據CONSTANT_Methodref_info表的結構繼續往下分析,一直到分析完18個常量池.在這里就不一一往下分析了,直接通過javap工具來直接查看,也順便查看我們分析的對不對.

 

 

我們從javap的結果看出,常量池的范圍就是1~18,然后第一個常量池就是Method,也即CONSTANT_Methodref_info.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM