Class文件規(guī)范
?根據(jù)《JAVA虛擬機(jī)規(guī)范》的規(guī)定,Class文件格式采用一種類似于C語言結(jié)構(gòu)體的偽結(jié)構(gòu)來存儲數(shù)據(jù),這種偽結(jié)構(gòu)中(Class文件格式中)只有兩種數(shù)據(jù)類型:“無符號數(shù)”和“表”。
?
?本篇文章圖中貼出的類型這一列也都是這兩個數(shù)據(jù)類型,如果類型是u開頭的表示為無符號數(shù)的數(shù)據(jù)類型,如果是_info結(jié)尾的表示是表類型。
?
- 無符號數(shù)就是正常的數(shù)字,以u1,u2,u4,u8來表示一個,兩個,四個,八個字節(jié),通常用來描述數(shù)字,索引引用,數(shù)量值或者用來表達(dá)字符串值。
?u1在Class文件中為兩個數(shù)字或字母,比如00,01,0A,6F ; u2在Class文件中為四個數(shù)字或字母,比如0001,000A,6C61;
?
- 表是用來描述復(fù)合結(jié)構(gòu)的數(shù)據(jù),它由無符號數(shù)或者其他表構(gòu)成,并在結(jié)尾處用“_info”表示。
?比如:cp_info為常量池表,field_info為字段表,method_info為方法表,attribute_info為屬性表。本篇文章會講解除了屬性表之外的其他表結(jié)構(gòu),屬性表單獨(dú)寫一篇文章進(jìn)行講解
?
- 本質(zhì)上Class結(jié)構(gòu)也是將表和無符號數(shù)組合起來的一張表。
Class文件大結(jié)構(gòu)總覽
后面講的所有結(jié)構(gòu)都是按照這個Class文件表講的,所以這張圖先看下。
magic
Class文件的 「頭四個字節(jié)」 表示魔數(shù),這個值存在于各個文件中,在之前的這篇文章里面講過這個字段:驗(yàn)證apk文件的magic,magic是用來驗(yàn)證是不是屬于某種結(jié)構(gòu)的,即使用戶更改了文件的后綴名也沒事,通過這個字段就可以看出他是什么類型的文件。「因此每一種文件格式的魔數(shù)magic都不一樣,因?yàn)槭怯脕肀硎酒鋵儆谀姆N文件格式的?!?/strong>
?Class文件的magic為0XCAFFBABE(咖啡寶貝)
?
Class文件版本號
接下來的兩個字節(jié)表達(dá)的Class文件的 「次版本號(Minor Version)」 ,再接著兩個字節(jié)表達(dá)的是 「主版本號(Major Version)」 。
?高版本的JDK能夠兼容低版本的Class文件,但是低版本的JDK不能運(yùn)行高版本的Class文件(規(guī)范中Class文件校驗(yàn)必須要求的?。?/p>
?
Constant_Pool常量池
1、Class文件中第一個出現(xiàn)的表結(jié)構(gòu)的數(shù)據(jù),主要存放兩種常量:「字面量和符號引用。」
?字面量:Java語言層面常量的概念。eg:字符串,被聲明為final的常量等
?
?符號引用:編譯原理方面的概念。eg:被模塊導(dǎo)出或者開放的包(Package) 類和接口的全限定名(也就是類所屬的包名和類的名字) 字段的名稱和描述符(名稱簡單理解就是字段名,描述符為字段所屬的類型) 方法的名稱和描述符(名稱簡單理解就是方法名,描述符為方法參數(shù)和返回值) 方法句柄和方法類型(Method Handle,Method Type,Invoke Dynamic) 動態(tài)調(diào)用點(diǎn)和動態(tài)常量
?
2、符號引用,由于Class文件是在編譯后生成的,因此運(yùn)行的時候需要 「將符號引用轉(zhuǎn)換為對應(yīng)數(shù)據(jù)在內(nèi)存中的地址」 ,否則使用的時候會找不到真正的內(nèi)存入口地址(也就是不能被虛擬機(jī)直接使用)。
?當(dāng)虛擬機(jī)做類加載的時候,會從常量池中拿出對應(yīng)的符號引用,在類創(chuàng)建或者運(yùn)行時解析,翻譯到具體的內(nèi)存地址之中 比如class文件的類名,當(dāng)類被加載到虛擬機(jī)中時,需要將這個符號引用轉(zhuǎn)換為類真實(shí)所在的內(nèi)存地址才能被正常訪問。
?
3.常量池中存儲的數(shù)據(jù)數(shù)量 「從1開始計(jì)數(shù)」 ,第0項(xiàng)常量空出來是因?yàn)橛行?shù)據(jù)并不需要引用常量池中的數(shù)據(jù)時,就可以用第0項(xiàng)常量來表達(dá)。
4.常量池的數(shù)據(jù)數(shù)量會在版本號之后用兩個字節(jié)來表達(dá),之后才是常量池中的數(shù)據(jù)
?這樣做是因?yàn)闆]有Class文件中 「沒有分隔符」 來表示一組數(shù)據(jù)結(jié)束,因此Class文件中的數(shù)據(jù)必須嚴(yán)格按照固定長度,固定數(shù)量去存放,不允許改變。
?
5.常量池中 「每一項(xiàng)常量數(shù)據(jù)都是一張表」 ,每個表結(jié)構(gòu)中都有一個u1類型的標(biāo)志位標(biāo)識自己屬于哪種類型的表。
各個表對應(yīng)的含義
這些表有著各自完全獨(dú)立的結(jié)構(gòu),之間沒有任何關(guān)聯(lián)。
反編譯代碼示例
C:\\>javap -verbose TestClass
Compiled from "TestClass.java"
public class org.fenixsoft.clazz.TestClass extends java.lang.Object SourceFile: "TestClass.java"
minor version: 0
major version: 50
Constant pool:
const #1 = class #2; // org/fenixsoft/clazz/TestClass
const #2 = Asciz org/fenixsoft/clazz/TestClass;
const #3 = class #4; // java/lang/Object
const #4 = Asciz java/lang/Object;
const #5 = Asciz m;
const #6 = Asciz I;
const #7 = Asciz ;
const #8 = Asciz ()V;
const #9 = Asciz Code;
const #10 = Method #3.#11; // java/lang/Object."":()V
const #11 = NameAndType #7:#8;// "":()V
const #12 = Asciz LineNumberTable;
const #13 = Asciz LocalVariableTable;
const #14 = Asciz this;
const #15 = Asciz Lorg/fenixsoft/clazz/TestClass;;
const #16 = Asciz inc;
const #17 = Asciz ()I;
const #18 = Field #1.#19; // org/fenixsoft/clazz/TestClass.m:I
const #19 = NameAndType #5:#6; // m:I
const #20 = Asciz SourceFile;
const #21 = Asciz TestClass.java;
代碼塊中Asciz就是之前說的Constant_UTF8_info常量(也就是字符串常量),可以看到這些數(shù)據(jù)都是由這個常量來組成的,
常量池中常量表對應(yīng)數(shù)據(jù)結(jié)構(gòu)內(nèi)容
第一列常量為之前 「各個表對應(yīng)的含義」 中提到的表結(jié)構(gòu)類型也就是表的名稱;
第二列中的項(xiàng)目為各個表中存放的不同的數(shù)據(jù)內(nèi)容有哪些,這些表的數(shù)據(jù)中都有一個標(biāo)識位tag用來標(biāo)識不同的表,在之前 「各個表對應(yīng)的含義」 中也提到過;
第三列為描述不同于之前講的表的描述,這列說明的是**「表中存儲的不同數(shù)據(jù)的描述」**
圖例:
-
JAVA
+關(guān)注
關(guān)注
19文章
2977瀏覽量
105239 -
C語言
+關(guān)注
關(guān)注
180文章
7616瀏覽量
137892 -
Class
+關(guān)注
關(guān)注
0文章
53瀏覽量
19777 -
存儲數(shù)據(jù)
+關(guān)注
關(guān)注
0文章
89瀏覽量
14156
發(fā)布評論請先 登錄
相關(guān)推薦
jvm的類加載器的整體結(jié)構(gòu)及過程解析
![<b class='flag-5'>jvm</b>的類加載器的整體<b class='flag-5'>結(jié)構(gòu)</b>及過程解析](https://file.elecfans.com/web1/M00/C8/88/o4YBAF9wQzuASvvjAAAYyn9-zNc508.png)
Jvm的整體結(jié)構(gòu)和特點(diǎn)
Jvm工作原理學(xué)習(xí)筆記
Java:JVM虛擬機(jī)的入門知識
![Java:<b class='flag-5'>JVM</b>虛擬機(jī)的<b class='flag-5'>入門</b>知識](https://file.elecfans.com/web1/M00/BF/B9/o4YBAF78BR-AHchxAAGQhzO2hWA656.png)
JVM入門之Class結(jié)構(gòu)介紹2
![<b class='flag-5'>JVM</b><b class='flag-5'>入門</b><b class='flag-5'>之</b><b class='flag-5'>Class</b><b class='flag-5'>結(jié)構(gòu)</b><b class='flag-5'>介紹</b>2](https://file.elecfans.com/web2/M00/90/15/pYYBAGPktA-AUpBtAAAkvqCZdjM669.png)
JVM入門之Class結(jié)構(gòu)屬性表1
![<b class='flag-5'>JVM</b><b class='flag-5'>入門</b><b class='flag-5'>之</b><b class='flag-5'>Class</b><b class='flag-5'>結(jié)構(gòu)</b>屬性表<b class='flag-5'>1</b>](https://file.elecfans.com/web2/M00/90/3E/pYYBAGPls16AG92RAAT2cB0CcY4811.jpg)
JVM入門之Class結(jié)構(gòu)屬性表2
![<b class='flag-5'>JVM</b><b class='flag-5'>入門</b><b class='flag-5'>之</b><b class='flag-5'>Class</b><b class='flag-5'>結(jié)構(gòu)</b>屬性表2](https://file.elecfans.com/web2/M00/8F/BA/poYBAGPls16ANZ7JAAN7Re9jKmQ120.jpg)
JVM入門之認(rèn)識程序運(yùn)行本質(zhì)
![<b class='flag-5'>JVM</b><b class='flag-5'>入門</b><b class='flag-5'>之</b>認(rèn)識程序運(yùn)行本質(zhì)](https://file.elecfans.com/web2/M00/8F/BF/poYBAGPlvmyAAUNfAAMULYXg0l0761.png)
垃圾收集器的JVM參數(shù)配置
![垃圾收集器的<b class='flag-5'>JVM</b>參數(shù)配置](https://file1.elecfans.com/web2/M00/A7/6D/wKgaomUjux-ANVLUAAChVNUuCZ0773.jpg)
評論