一、常量池的內容
一個java類中定義的很多信息都是由常量池來維護和描述的,可以將常量池看作是class文件的資源倉庫,比如java類中定義的方法與變量信息。常量池中主要存儲兩類常量:字面量(文本字符串,final的常量)與符號引用(類和接口的全限定名,字段的名稱和描述符,方法的名稱和描述符
一、常量池的結構

二、常量池的分析

常量池(也稱常量表):主版本號之后就是常量池的開始位置;java類所對應的常量池主要由常量池數量和常量池數組兩部分組成,常量池數量是主版本號之后的兩個字節;常量池數組在常量池數量之后,常量池數組中不同元素的類型,結構是不同的,所以該數組長度是不同的,但是數組中的每一種元素的第一個字節是標記位是一個u1類型,JVM在解析常量池時會根據這u1類型來獲取元素的具體類型。
1、常量池元素的數量:
00 18(24):就是該class字節碼文件的常量池數量; 常量池數組元素的個數=常量池數量-1;索引為0的位置暫不使用,目的是滿足某些常量池索引值的數據在特定情況下需要表達,不引用任何一個常量池的含義。根本原因是索引為零也是一個常量,只是他不在常量池中,該常量對應null值,所以常量池的索引從1開始(#1)。

2、常量池數組
第一個元素:根據Constant pool 中 #1的描述可知該元素是無參的構造函數
0A(10):常量池元素數量之后的第一個字節,u1=10 對應

第一個u2(4):占兩個字節即00 04;第二個u2(20):占兩個字節即00 14;所以該常量池的第一個元素占五個字節即0A 00 04 00 14
第二個元素:根據 Constant pool 中#2的描述可知該元素是在類ByteCodeTest中一個int 類型 名字為num的變量,
09(9):第一個元素之后的第一個字節 ,u1=9 對應

第一個u2(3):占兩字節00 03;第二個u2(15):占兩個字節00 15;所以該常量池的第二個元素占五個字節即09 00 03 00 15
第三個元素:根據 Constant pool 中#3 可知該元素是該類的權限定名。
07(7):第二個元素之后的第一個字節07 ,u1=7 對應

u2(16):占兩個字節00 16;所以該常量池的第三個元素占三個字節即07 00 16
第四個元素:根據 Constant pool 中#4 可知該元素是該Object類的權限定名。
07(7):第三個元素之后的第一個字節07 ,u1=7 對應

u2(17):占兩個字節00 17;所以該常量池的第四個元素占三個字節即07 00 17
第五個元素:根據Constant pool 中#5的描述該元素是字符num
01(1):第四個元素之后的第一個字節01 ,u1=1 對應

u2(03):占兩個字節00 03,表示utf-8格式的內容對應的長度是3個字節;u1:對應三個字節 6e 75 6d, 所以該常量池的第五個元素占6個字節即01 00 03 6e 75 6d;0x6e756d轉字符串=num;
第六個元素:根據Constant pool 中#5的描述該元素是字符I
01(1):第五個元素之后的第一個字節01 ,u1=1 對應

u2(01):占兩個字節00 01,表示utf-8格式的內容對應的長度是1個字節;u1(73):對應1個字節 49; 所以該常量池的第劉個元素占4個字節即01 00 01 49;49轉十進制73;
根據ASCII字碼表可知49=73=I;
![]()
其他元素分析方式與此相同就不再分析,最終分析可知紅圈這部分區域是常量池的內容(00 18->63 74)

三、JVM描述符
在jvm規范中,每個變量或字段都有描述信息,描述信息主要的作用是描述字段的數據類型,方法的參數列表(包括數量,類型與順序)與返回值。
1、為了壓縮字節碼文件的體積,JVM對於基本數據類型和代表無返回值的void類型都用一個大寫字符來表示,而對象類型用字符L加對象的全限定類名來表示
如下表示:B--byte,C--Char,D--double,F--float,I--int,J--long,S--short,Z--boolean,V--void,L--對象類型如Ljava/lang/String。
2、對於數組來說,每一個維度使用一個前置的[來表示,如Int[]表示為[I,String[][]表示為[[Ljava/kang/Stirng;

3、用描述符來描述方法時,用先參數列表后返回值的順序來描述,參數列表按照參數的嚴格順序放在一組()之內,如方法:String getNameById(int id,String name)的描述符為:(I,Ljava/lang/String) Ljava/lang/String;
public String getNameById(int id,String name){ return name; }

