類的載入由JVM執行引擎來完成
早期--編譯期:原始碼檔案*.java -> 詞法分析器 -> tokens流 -> 語法分析器 -> 語法樹/抽象語法樹 -> 語義分析器 -> 註解抽象語法樹 -> 位元組碼生成器 -> JVM位元組碼檔案*.class
晚期--執行期==執行引擎執行:JVM位元組碼 .class -> 機器無關優化 -> 中間程式碼 -> 機器相關優化 -> 中間程式碼 -> 暫存器分配器 -> 中間程式碼 -> 目標機器碼生成器 -> 目標機器碼
1:類的生命週期:
載入、驗證、準備、解析、初始化、使用、銷燬,其中驗證、準備、解析統稱為連線
載入、驗證、準備、初始化和解除安裝順序確定,過程通常互相交叉混合式進行,通常在一個階段執行的過程中呼叫、啟用另一個階段;
解析在某些情況下可以在初始化之後再開始---支援Java語言的執行時繫結(也稱動態繫結或晚期繫結)
虛擬機器規範嚴格規定了有且只有五種情況必須對類進行初始化,也就是執行類載入操作,而載入、驗證、準備自然需要在此之前進行
五種情況被稱為主動引用----觸發初始化操作(page 210), 其他的引用類方式都不會觸發初始化,成為被動引用
2:類載入的全過程
-----載入、驗證、準備、解析、初始化,其中驗證、準備、解析過程完全由虛擬機器主導和控制,類載入也可以通過自定義類載入器,初始化階段執行程式設計師編寫的Java程式程式碼(轉化後的位元組碼)
載入:完成3件事==1)通過類的全限定名來獲取定義此類的二進位制位元組流--位元組流來源:zip包中、網路、執行時計算生成(動態代理)、其他檔案(jsp)、資料庫中讀取(少見)
2)將這個位元組流所代表的京塔儲存結構轉化為方法區的執行時資料結構
3)在記憶體(沒有明確規定在堆中,而是在方法區中)中生成一個代表這個類的java.lang.Class物件,作為方法區這個類的各種資料的訪問入口
說明:載入階段與連線階段的部分內容(部分位元組碼檔案格式的驗證)一般是交叉進行的
驗證:確保Class檔案的位元組流中包含的資訊符合當前虛擬機器的要求,並且不會危害虛擬機器自身的安全
包括檔案格式驗證、後設資料驗證、位元組碼驗證、符號引用驗證(在解析階段發生)
準備:準備階段是正式為類的變數(屬性)分配記憶體並設定類變數初始值(通常為0)的階段,這些變數所使用的的記憶體都將在方法區中進行分配
解析:解析階段是虛擬機器將常量池內的符號引用替換為直接引用的過程,主要針對類或介面、欄位、類方法、介面方法、方法型別、方法控制程式碼和呼叫點限定符這七類符號引用
初始化:執行程式設計師編寫的Java程式程式碼(轉化後的位元組碼),初始化變數和其他資源---執行類構造器<clinit>()方法的過程,特點和細節見 page225
3:類載入器
類載入器和類本身一同確立其在Java虛擬機器中的唯一性,每個類載入器都有獨立的類名稱空間;
雙親委派模型:啟動類載入器(Bootstrap ClassLoader)---載入<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath引數所指定的且被虛擬機器識別的類,開發者不能直接使用
擴充套件類載入器(Extension ClassLoader)---載入<JAVA_HOME>\lib\ext目錄中的或者被java.ext.dirs系統變數所指定的路徑中的所有類庫,開發者可直接使用
應用程式類載入器(Application ClassLoader)---也稱系統類載入器,載入使用者類路徑ClassPath指定的類庫,開發者可直接使用,程式中預設的類載入器
破壞雙親委派模型:程式碼熱替換、模組熱部署、開放服務閘道器協議OSGi(Open Service Gateway Initiative)
4:虛擬機器位元組碼執行引擎