在.java文件,講過javac編譯后產生的 .class文件中,頭4個字節表示的是魔數,接着魔數后面的第5,6個字節存儲的是次版本號,第7,8個字節存儲的主板本號.那么再接下來的就是表示常量池入口了.
常量池
可以理解為class文件之中的資源倉庫,它是class文件結構中與其他項目關聯最多的數據類型,也是占用class文件空間最大的數據項目之一,同時它還是class文件中第一個出現表類型的數據項目.由於常量池的數量是不固定的,所以在常量池入口需要放置一項u2(即2個字節)類型的數據,代表常量池容量計數值(constant-pool-count)(從1開始,將0表示不引用任何常量).
常量池中主要存放兩大類常量:字面量(Literal)和符號引用(Synbolic Reference).
- 字面量:比較接近於Java語言層面的常量概念,如文本字符串,聲明為final的常量值.
- 符號引用:包括如下三類常量:
- 類和接口的全限定名(Fully Qualified Name)
- 字段的名稱和描述符(Descriptor)
- 方法的名稱和描述符
常量池中每一項常量都是一個表(14種表).
類型 | 標志 | 描述 |
CONSTANT_utf8_info | 1 | UTF-8編碼的字符串 |
CONSTANT_Integer_info | 3 | 整形字面量 |
CONSTANT_Float_info | 4 | 浮點型字面量 |
CONSTANT_Long_info | 5 | 長整型字面量 |
CONSTANT_Double_info | 6 | 雙精度浮點型字面量 |
CONSTANT_Class_info | 7 | 類或接口的符號引用 |
CONSTANT_String_info | 8 | 字符串類型字面量 |
CONSTANT_Fieldref_info | 9 | 字段的符號引用 |
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文件繼續往下走.
