虛擬機加載類的過程
從class文件到內(nèi)存中的類,總體來說分為三個階段:加載伏恐、鏈接以及初始化
加載
- 加載纠脾,是指查找字節(jié)流玛瘸,并根據(jù)其創(chuàng)建類的過程。這個字節(jié)流乳乌,通常是來自于class文件捧韵。Java虛擬機需要借助類加載器來完成查找字節(jié)流這一過程。
- 雙親委派模型:每當一個類加載器接收到加載請求時汉操,它會先將請求轉(zhuǎn)發(fā)給父類加載器再来。在父類加載器沒有找到所請求的類的情況下,該類加載器才會嘗試去加載磷瘤。
- 啟動類加載器(bootstrap class loader) 由C++實現(xiàn)的芒篷,沒有對應的Java對象。負責加載最基礎采缚、最重要的類 例如 JRE lib 目錄下jar包中的類针炉。還有其他兩個比較重要的類加載器: 擴展類加載器(extension class loader)和應用類加載器(application class loader) 這兩個由Java的核心類庫提供。
- 擴展類加載器的父類加載器是啟動類加載器扳抽。它加載相對次要篡帕,但通用的類殖侵。例如存放在 lib/ext 目錄下jar包中的類。
- 應用類加載器的父類加載器是擴展類加載器镰烧。它加載應用程序路徑下的類拢军。
- Java9 引入了模塊系統(tǒng)。擴展類加載器改名為平臺類加載器怔鳖。JavaSE中的除了少數(shù)模塊由啟動類加載器加載茉唉,如java.base,其他模塊由平臺類加載器加載结执。平臺類加載器由原來的擴展類加載器進一步拓展了度陆。。搶了父類加載器的活献幔?懂傀?
- 類加載器除了加載功能外還有命名空間的作用。在Java虛擬機中斜姥,類的唯一性是由類加載器實例和類的全名一同確定的鸿竖。
鏈接
- 鏈接是指將創(chuàng)建的類合并至Java虛擬機,使之能夠執(zhí)行的過程铸敏「坑牵可分為驗證、準備和解析三個階段杈笔。
- 驗證:確保被加載類能夠滿足虛擬機的約束條件闪水。
- 準備:為被加載類的靜態(tài)字段分配內(nèi)存。
- 解析:對于一個方法調(diào)用蒙具,編譯器會生成一個包含目標方法所在類的名字球榆、目標方法的名字、接收參數(shù)類型以及返回值類型的符號引用禁筏,來指代所要調(diào)用的方法持钉。解析階段的目的,正是將這些符號引用解析成為實際引用篱昔。如果這個符號引用指向一個未被加載的類或者未被加載類的字段或方法每强,那么這時會觸發(fā)這個類的加載。
初始化
- 初始化是指對標記為常量值的字段進行賦值州刽,以及執(zhí)行<clinit>方法的過程空执。類的初始化只會執(zhí)行一次。