LocalVariableTable,LocalVariableTypeTable
1.「LocalVariableTable」
?用于描述局部變量表中的變量與JAVA代碼中定義變量之間的關(guān)系,同樣也可以選擇不生成該屬性
?
?用處:當(dāng)編寫代碼引用到這個方法時,參數(shù)可以直接顯示變量名和類型,如果沒有該屬性,就用arg0,arg1代替;調(diào)試信息的時候可以根據(jù)參數(shù)變量名明確語義。
?
2.「LocalVariableTypeTable」
?引入泛型后加入的屬性,結(jié)構(gòu)和LocalVariableTable相似,將原先用于描述字段描述符的descriptor_index替換成了描述字段的特征簽名(Signature)。
?
?對于非泛型變量,特征簽名和描述符是一致的,但是對于泛型來說,由于泛型參數(shù)類型的擦除,描述符不能夠描述泛型類型,因此定義了該屬性來完成泛型的描述。
?
結(jié)構(gòu):
ConstantValue
「變量初始化,賦值時機(jī):」 位于該屬性結(jié)構(gòu)中的常量將會在類加載的準(zhǔn)備階段就會初始化并且賦值;
其他的靜態(tài)變量在這個階段只是會被初始化然后賦默認(rèn)值,如果靜態(tài)變量設(shè)置了final關(guān)鍵字,那么就是第一種情況會對變量進(jìn)行賦值;
對于實例變量(非靜態(tài)變量)的賦值是在實例構(gòu)造器《init》中。
「該結(jié)構(gòu)中存放的字段是:」
「《Java虛擬機(jī)規(guī)范》中規(guī)定該屬性結(jié)構(gòu)中存放的必須是靜態(tài)的字段,而對于javac編譯器來說還需要滿足final關(guān)鍵字的修飾,因此經(jīng)過javac編譯器編譯后的該屬性中存放的字段必須是static并且是final的?!?/strong>
?通知虛擬機(jī)自動為靜態(tài)變量賦值(上面那句話)。該屬性中只能存放基本類型和String,因為該屬性的屬性值
?
結(jié)構(gòu):
Deprecated及Synthetic屬性
?這兩項屬性有點特殊,不攜帶任何屬性值,出現(xiàn)這兩個屬性的目的只是為了標(biāo)識,這兩個屬性只有存在或不存在。
?
- 「Deprecated屬性」 該屬性用于表示某個類,字段或方法已經(jīng)不再推薦使用,通過“@deprecated”注解設(shè)置這個屬性
2.「Synthetic屬性」
該屬性用于表示字段或者方法是編譯器自己添加的,不是代碼中的。也可以通過設(shè)置訪問標(biāo)志ACC_SYNTHETIC標(biāo)志位生成該項屬性。
結(jié)構(gòu):兩者都一樣,不攜帶任何屬性值。只是用于標(biāo)識
StackMapTable
「該屬性位于Code屬性的屬性表中」
?用處:在類加載階段的驗證階段使用該屬性,代替以前耗性能的基于數(shù)據(jù)流分析的類型推導(dǎo)驗證器(有了該屬性之后就不用類型推導(dǎo)了,可以直接判斷類型是不是符合要求,之后單獨寫類加載階段進(jìn)行分析)
?
?之前驗證階段是基于數(shù)據(jù)流來進(jìn)行分析推導(dǎo)出操作數(shù)棧和本地變量表操作的類型是否一致等(比如istore需要將操作數(shù)棧的數(shù)據(jù)保存到本地變量表中,但是取出的數(shù)據(jù)類型不是int就會發(fā)生問題),現(xiàn)在基于該項屬性可以不用推導(dǎo)
?
結(jié)構(gòu):「一個Code屬性最多只能有一個StackMapTable屬性」
MethodParameters
「用于記錄方法的各個形參名稱和信息」
方法參數(shù)屬性,位于class中的屬性表中。之前說過這部分是存儲在局部變量表中的,因為方法中有方法體code屬性,而code中需要有局部變量表屬性代表這個方法中的變量存儲。
但是為什么還要單獨抽出一個屬性放在class中呢?
大家想想沒有code就沒有局部變量表,沒有局部變量表是不是就不能存儲方法參數(shù)了;你看接口中他有方法吧但是呢他其實沒有方法提code所以它的方法參數(shù)往哪放呢?往他借口的屬性表集合中放,也就是與code同級。這樣的話我接口里可以直接獲得方法參數(shù)通過這個屬性;而對于正常的方法也就是有方法體的代碼可以從code中的局部變量表中拿。
數(shù)據(jù)結(jié)構(gòu):1.首先說明他是什么,我是一個方法參數(shù)類型 2.我說明我存儲的時候數(shù)據(jù)有多長(多少字節(jié)),為了切割按照這個就可以正確讀取對應(yīng)的數(shù)據(jù);但是如果這個屬性中還用到了其他的數(shù)據(jù)結(jié)構(gòu)(屬性),那么就是這個屬性的個數(shù)了
3.對于沒有再次用到其他屬性來描述的屬性直接使用定長數(shù)據(jù)即可;但是對于有用到其他屬性來描述這個屬性的話,則后面是對應(yīng)的屬性一個一個排開,然后每個屬性如果是定長的話則不需要通過長度來說明所占字節(jié),然后這個屬性中存儲的第一個永遠(yuǎn)是他是什么也就是名字,然后再是對應(yīng)的值
不斷使用這種結(jié)構(gòu)來描述一個完整的class結(jié)構(gòu)
結(jié)構(gòu):
-
JAVA
+關(guān)注
關(guān)注
19文章
2969瀏覽量
104789 -
Class
+關(guān)注
關(guān)注
0文章
53瀏覽量
19745 -
JVM
+關(guān)注
關(guān)注
0文章
158瀏覽量
12236
發(fā)布評論請先 登錄
相關(guān)推薦
評論