access_flags訪(fǎng)問(wèn)標(biāo)識(shí)
常量池結(jié)束后就是這個(gè)Class對(duì)應(yīng)的訪(fǎng)問(wèn)標(biāo)志內(nèi)容,用u2(兩個(gè)字節(jié))來(lái)表示。
?訪(fǎng)問(wèn)標(biāo)志可以有多個(gè),根據(jù)多個(gè)標(biāo)志位的或運(yùn)算來(lái)決定最終的access_flags的取值
?
class的繼承實(shí)現(xiàn)關(guān)系
訪(fǎng)問(wèn)標(biāo)志之后的是this_class,super_class,interfaces_count,interfaces這些數(shù)據(jù)。1.this_class:該Class的權(quán)限定名。( 「通過(guò)訪(fǎng)問(wèn)常量池中的類(lèi)信息表來(lái)定位到類(lèi)的權(quán)限定名」 )2.super_class:父類(lèi)的全限定名。(由于Java中是 「單繼承多實(shí)現(xiàn)」 的,所以父類(lèi)索引只有一個(gè),但是接口可以有多個(gè)稍后將),跟上面的尋找過(guò)程類(lèi)似,只不過(guò)換了一個(gè)常量池的索引,「如果沒(méi)有顯示使用繼承的話(huà)那么最終引用的是Object類(lèi)的權(quán)限定名,如果明確使用了繼承自哪個(gè)類(lèi)那么最終引用到的就是那個(gè)類(lèi)的權(quán)限定名」
3.interfaces和interfaces_count 剛剛說(shuō)了Class是可以多實(shí)現(xiàn)的,所以
interfaces_count為 「該Class實(shí)現(xiàn)接口的數(shù)量」 (如果沒(méi)有任何實(shí)現(xiàn)的接口,那么該值為0后面的interfaces將沒(méi)有數(shù)據(jù)不占用任何字節(jié));
interfaces為實(shí)現(xiàn)接口的對(duì)應(yīng)接口的全限定名
字段表
「該表結(jié)構(gòu)用于描述接口/類(lèi)中聲明的變量」 。
變量可以分為類(lèi)變量(static級(jí)別的),實(shí)例變量。
?注意:該部分不包括方法中的局部變量字段,局部變量會(huì)有一個(gè)單獨(dú)的局部變量表來(lái)存儲(chǔ),下一篇文章講解。對(duì)于Class文件中最外層的字段表中存儲(chǔ)的只是類(lèi)變量和實(shí)例變量。
?
而字段有哪些數(shù)據(jù)需要表示呢?權(quán)限修飾符,字段名稱(chēng),字段數(shù)據(jù)類(lèi)型,類(lèi)級(jí)別還是實(shí)例級(jí)別(是否有static修飾符),可變性(final),并發(fā)可見(jiàn)性(volatile修飾符,強(qiáng)制從主內(nèi)存讀寫(xiě)),是否可以被序列化(transient修飾符)
access_flags訪(fǎng)問(wèn)標(biāo)識(shí)
這個(gè)訪(fǎng)問(wèn)標(biāo)識(shí)和前面講的類(lèi)的access_flags不一樣,這個(gè)是字段的訪(fǎng)問(wèn)標(biāo)識(shí)
名稱(chēng)索引和描述符的索引
這兩個(gè)索引都是在常量池中的索引,對(duì)常量池的引用
name_index為 「字段的名稱(chēng)」 descriptor_index為描述符,對(duì)應(yīng)于字段來(lái)說(shuō)是該**「字段的數(shù)據(jù)類(lèi)型」**
描述符的含義:
?對(duì)于一維數(shù)組來(lái)說(shuō)使用“[”來(lái)表示,如果是二位就用兩個(gè)“[[”。比如類(lèi)型為String的二維數(shù)組(String[][])用描述符來(lái)表示就是[[ java.lang.String;一維數(shù)組“int[]”就是[I
?
存儲(chǔ)額外信息
可以看到描述符后面還有一個(gè)屬性表集合,該集合是用來(lái)**「存儲(chǔ)一些額外的信息,可以添加0到多個(gè)信息?!?*
如果沒(méi)有額外描述的信息attributes_count就是0,后面沒(méi)有字節(jié)去描述屬性表;如果有額外的信息比如將字段聲明為final的話(huà),屬性表中就會(huì)存儲(chǔ)一個(gè)ConstantValue的屬性,這個(gè)值指向?qū)?yīng)的常量值。(關(guān)于這部分內(nèi)容之后進(jìn)行詳解)
?該字段表中不會(huì)記錄父類(lèi)中或者父接口中繼承來(lái)的字段,但是有可能出現(xiàn)原本不存在的字段,比如在內(nèi)部類(lèi)中添加字段來(lái)訪(fǎng)問(wèn)外部類(lèi)。
?
?重載字段:對(duì)于Class文件來(lái)說(shuō)剛剛看了,只要描述符不一致,字段名一樣也是可以被記錄到Class中的而不會(huì)引起沖突;但是對(duì)于Java語(yǔ)言來(lái)說(shuō)字段是不能重載的,不管描述符一樣不一樣,「名稱(chēng)必須不一樣?。?!」
?
方法表
「該表結(jié)構(gòu)用于描述接口/類(lèi)中聲明的變量」
「圖例:」
可以看到和上面講的字段表結(jié)構(gòu)大致是一樣的。
access_flags訪(fǎng)問(wèn)標(biāo)識(shí)
名稱(chēng)索引和描述符的索引
這兩個(gè)索引都是在常量池中的索引,對(duì)常量池的引用
name_index為 「方法的名稱(chēng)」 descriptor_index為描述符,對(duì)應(yīng)于方法來(lái)說(shuō)是該 「方法的參數(shù)集合和返回值類(lèi)型」 對(duì)應(yīng)的數(shù)據(jù)在上面講字段表的時(shí)候已經(jīng)貼過(guò)圖,不在說(shuō)明。
存儲(chǔ)額外信息
這個(gè)里面的屬性表中就會(huì)有各種各樣的表來(lái)存儲(chǔ)一個(gè)方法的額外信息,比如方法體中的代碼,局部變量表等等表結(jié)構(gòu)數(shù)據(jù)類(lèi)型。(下一篇文章進(jìn)行詳解)
?和字段表一樣如果父類(lèi)方法沒(méi)有被子類(lèi)重寫(xiě),那么該表中不會(huì)記錄父類(lèi)方法的信息的,但是同樣可以出現(xiàn)一些編譯器添加的方法,比如類(lèi)構(gòu)造器clvinit()和實(shí)例構(gòu)造器init()
?
?重載方法:名稱(chēng)一樣,方法的特征簽名不一樣。對(duì)于Class文件來(lái)說(shuō)方法的特征簽名不同(描述符不完全一致)就可以進(jìn)行重載不會(huì)發(fā)生沖突;但是對(duì)于Java語(yǔ)言來(lái)說(shuō)方法的特征簽名中不包括返回值這個(gè)條件所以返回值不同不能作為重載的條件 Java代碼層面的方法特征簽名,Java代碼的方法特征簽名只包括方法名稱(chēng)、參數(shù)順序及參數(shù)類(lèi)型,而字節(jié)碼Class的特征簽名還包括方法返回值以及受查異常表,請(qǐng)讀者根據(jù)上下文語(yǔ)境注意區(qū)分。
-
JAVA
+關(guān)注
關(guān)注
20文章
2988瀏覽量
108694 -
C語(yǔ)言
+關(guān)注
關(guān)注
180文章
7631瀏覽量
141160 -
Class
+關(guān)注
關(guān)注
0文章
53瀏覽量
20064 -
JVM
+關(guān)注
關(guān)注
0文章
160瀏覽量
12579
發(fā)布評(píng)論請(qǐng)先 登錄
jvm的類(lèi)加載器的整體結(jié)構(gòu)及過(guò)程解析

Proteus基礎(chǔ)入門(mén)教程 之 Proteus界面功能介紹及常用操作
Jvm的整體結(jié)構(gòu)和特點(diǎn)
Jvm工作原理學(xué)習(xí)筆記
Java:JVM虛擬機(jī)的入門(mén)知識(shí)

JVM入門(mén)之Class結(jié)構(gòu)介紹1

JVM入門(mén)之Class結(jié)構(gòu)屬性表1

JVM入門(mén)之Class結(jié)構(gòu)屬性表2

垃圾收集器的JVM參數(shù)配置

評(píng)論