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