Java類別載入過程
首先是載入過程(Loading),它是Java 將字節碼資料從不同的資料來源讀取取到JVM 中,並映射為JVM 認可的資料結構(Class 物件),這裡的資料來源可能是各種各樣的形態,例如jar 文件,class 文件,甚至是網路資料來源等;如果輸入資料不是ClassFile的結構,則會拋出ClassFormatError。載入階段是使用者參與的階段,我們可以自訂類別載入器,去實作自己的類別載入過程。
第二階段是連結(Linking),這是核心的步驟,簡單說是把原始的類別定義資訊平滑地轉入 JVM 運作的過程中。這裡可進一步細分成三個步驟:1,驗證(Verification),這是虛擬機器安全的重要保障,JVM 需要核驗位元組資訊是符合Java 虛擬機器規範的,否則就被認為是VerifyError,這樣就防止了惡意資訊或不合規資訊危害JVM 的運行,驗證階段有可能觸發更多class 的載入。 2,準備(Pereparation),建立類別或介面中的靜態變量,並初始化靜態變數的初始值。但這裡的「初始化」和下面的顯示初始化階段是有差別的,重點在於分配所需的記憶體空間,不會去執行更進一步的 JVM 指令。 3,解析(Resolution),在這一步驟會將常數池中的符號參考(symbolic reference)替換為直接引用。在 Java 虛擬機規範中,詳細介紹了類,接口,方法和字段等各方面的解析。
最後是初始化階段(initialization),這一步真正去執行類別初始化的程式碼邏輯,包括靜態欄位賦值的動作,以及執行類別定義中的靜態初始化區塊內的邏輯,編譯器在編譯階段就會把這部分邏輯整理好,父類型的初始化邏輯優先於當前類型的邏輯。再來談談雙親委派模型,簡單說就是當載入器(Class-Loader)試圖載入某個類型的時候,除非父類載入器找不到對應類型,否則盡量將這個任務代理給目前載入器的父載入器去做。使用委派模型的目的是避免重複載入 Java 類型。
自訂類別載入器的常見場景
實現類似進程內隔離,類別載入器實際上用作不同的命名空間,以及提供類似容器,模組化的效果。例如:1,兩個模組依賴某個類別庫的不同版本,如果分別被不同的容器加載,就可以互不干擾。這個面向的集大成者是 Jave EE 和 OSGL,JPMS等框架。 2,應用程式需要從不同的資料來源取得類別定義訊息,例如網路資料來源,而不是本機檔案系統。 3,或是需要自己操縱字節碼,動態修改生成類型。
我們可以大致簡單地理解自訂類別載入流程:1,透過指定名稱,找到其二進位實現,這裡往往就是自訂類別載入器會「自訂」的部分,例如,在特定資料來源根據名字取得字節碼,或修改或產生字節碼。 2,然後,建立 Class 對象,並完成類別載入程序。二進位資訊到 class 物件的轉換,通常就依賴 defineClass,我們不需要自己實現,它是 final 方法。有了 Class 對象,後續完成載入過程就順利成章了。
推薦教學:《Java教學》
以上是Java類別載入過程的詳細內容。更多資訊請關注PHP中文網其他相關文章!