類的解析過程

類或接口的解析

假設(shè)當前代碼所處的類為D,如果要把一個從未解析過的符號引用N解析為一個類或接口C的直接引用,那虛擬機完成整個解析的過程需要以下3個步驟:

  1. 如果C不是一個數(shù)組類型,那虛擬機將會把代表N的全限定名傳遞給D的類加載器去加載這個類C。在加載過程中,由于元數(shù)據(jù)驗證、字節(jié)碼驗證的需要,又可能觸發(fā)其他相關(guān)類的加載動作,例如加載這個類的父類或?qū)崿F(xiàn)的接口。一旦這個加載過程出現(xiàn)了任何異常,解析過程就宣告失敗。

  2. 如果C是一個數(shù)組類型,并且數(shù)組的元素類型為對象,也就是N的描述符會是類似“[Ljava/lang/Integer”的形式,那將會按照第1點的規(guī)則加載數(shù)組元素類型。如果N的描述符如前面所假設(shè)的形式,需要加載的元素類型就是“java.lang.Integer”,接著由虛擬機生成一個代表此數(shù)組維度和元素的數(shù)組對象。

  3. 如果上面的步驟沒有出現(xiàn)任何異常,那么C在虛擬機中實際上已經(jīng)成為一個有效的類或接口了,但在解析完成之前還要進行符號引用驗證,確認D是否具備對C的訪問權(quán)限。如果發(fā)現(xiàn)不具備訪問權(quán)限,將拋出java.lang.IllegalAccessError異常。

字段解析

要解析一個未被解析過的字段符號引用,首先將會對字段表內(nèi)class_index項中索引的CONSTANT_Class_info符號引用進行解析,也就是字段所屬的類或接口的符號引用。如果在解析這個類或接口符號引用的過程中出現(xiàn)了任何異常,都會導(dǎo)致字段符號引用解析的失敗。如果解析成功完成,那將這個字段所屬的類或接口用C表示,虛擬機規(guī)范要求按照如下步驟對C進行后續(xù)字段的搜索。

  1. 如果C本身就包含了簡單名稱和字段描述符都與目標相匹配的字段,則返回這個字段的直接引用,查找結(jié)束。

  2. 否則,如果在C中實現(xiàn)了接口,將會按照繼承關(guān)系從下往上遞歸搜索各個接口和它的父接口,如果接口中包含了簡單名稱和字段描述符都與目標相匹配的字段,則返回這個字段的直接引用,查找結(jié)束。

  3. 否則,如果C不是java.lang.Object的話,將會按照繼承關(guān)系從下往上遞歸搜索其父類,如果在父類中包含了簡單名稱和字段描述符都與目標相匹配的字段,則返回這個字段的直接引用,查找結(jié)束。

  4. 否則,查找失敗,拋出java.lang.NoSuchFieldError異常。

  5. 如果查找過程成功返回了引用,將會對這個字段進行權(quán)限驗證,如果發(fā)現(xiàn)不具備對字段的訪問權(quán)限,將拋出java.lang.Ille-galAccessError異常。

類方法解析

類方法解析的第一個步驟與字段解析一樣,也需要先解析出類方法表的class_index項中索引的方法所屬的類或接口的符號引用,如果解析成功,我們依然用C表示這個類,接下來虛擬機將會按照如下步驟進行后續(xù)的類方法搜索。

  1. 類方法和接口方法符號引用的常量類型定義是分開的,如果在類方法表中發(fā)現(xiàn)class_index中索引的C是個接口,那就直接拋出java.lang.IncompatibleClassChangeError異常。

  2. 如果通過了第1步,在類C中查找是否有簡單名稱和描述符都與目標相匹配的方法,如果有則返回這個方法的直接引用,查找結(jié)束。

  3. 否則,在類C的父類中遞歸查找是否有簡單名稱和描述符都與目標相匹配的方法,如果有則返回這個方法的直接引用,查找結(jié)束。

  4. 否則,在類C實現(xiàn)的接口列表及它們的父接口之中遞歸查找是否有簡單名稱和描述符都與目標相匹配的方法,如果存在匹配的方法,說明類C是一個抽象類,這時查找結(jié)束,拋出java.lang.AbstractMethodError異常。

  5. 否則,宣告方法查找失敗,拋出java.lang.NoSuchMeth-odError。

  6. 最后,如果查找過程成功返回了直接引用,將會對這個方法進行權(quán)限驗證,如果發(fā)現(xiàn)不具備對此方法的訪問權(quán)限,將拋出java.lang.IllegalAccessError異常。

接口方法解析

接口方法也需要先解析出接口方法表的class_index項中索引的方法所屬的類或接口的符號引用,如果解析成功,依然用C表示這個接口,接下來虛擬機將會按照如下步驟進行后續(xù)的接口方法搜索。

  1. 與類方法解析不同,如果在接口方法表中發(fā)現(xiàn)class_index中的索引C是個類而不是接口,那就直接拋出java.lang.Incom-patibleClassChangeError異常。

  2. 否則,在接口C中查找是否有簡單名稱和描述符都與目標相匹配的方法,如果有則返回這個方法的直接引用,查找結(jié)束。

  3. 否則,在接口C的父接口中遞歸查找,直到j(luò)ava.lang.Object類(查找范圍會包括Object類)為止,看是否有簡單名稱和描述符都與目標相匹配的方法,如果有則返回這個方法的直接引用,查找結(jié)束。

  4. 否則,宣告方法查找失敗,拋出java.lang.NoSuchMeth-odError異常。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.加載,將二進制字節(jié)流加載到方法區(qū),然后在java堆中實例化一個java.lang.Class類的對象2.驗證:...
    蒸汽飛船閱讀 843評論 0 0
  • 1.加載,將二進制字節(jié)流加載到方法區(qū),然后在java堆中實例化一個java.lang.Class類的對象2.驗證:...
    蒸汽飛船閱讀 306評論 0 0
  • 今天下午四點半左右聽到清脆的雷聲,這是今年的首次春雷,近五點雨開始下了起來,雖說正值下班時間行車不是很方便,雨刷也...
    孫德娟欣欣兒閱讀 372評論 0 0
  • 當一個人做自己喜歡的事情時,心情也會隨之開心,雖然我現(xiàn)在一直在臨摹別人的作品,但是日積月累中,總會慢慢進步。每個人...
    予安安閱讀 304評論 0 0
  • Apk改之理(ApkIDE)下載地址:點擊這里(還是舊版本哦!),apkide短期內(nèi)或長期內(nèi)或永久不會更新(現(xiàn)在不...
    鰻駝螺閱讀 6,786評論 15 1

友情鏈接更多精彩內(nèi)容