Java类加载机制总结
加載(Loading)
加載過程是Java的一大特點,類的來源可以多種多樣,壓縮包、網絡字節流、運行時動態計算生成(reflect)等等...這也造就了Java語言強大的動態特性。
java.lang.Class驗證(Verification)
這一過程主要是為了確保Class的字節流中包含的信息符合虛擬機標準,以免造成破壞
準備(Preparation)
這一階段將會為類變量分配內存并設置其初始值,注意此時進行內存分配的僅包括類變量(static修飾),并且初始值通常情況下是數據類型的零值而不是設定值,如下例
public static int val = 123; 復制代碼在這一階段變量?val?的賦值是0而不是123,因為此時尚未執行任何Java方法,而對?val?復制的?putstatic?指令在初始化階段后才會執行。
當然也有特殊情況,如下
public static final int val = 123; 復制代碼加上final關鍵字修飾后,Java編譯時會為?val?生成?ConstantValue?屬性,這時準備階段就會根據設置將其值設置為123。
解析(Resolution)
此階段虛擬機將常量池內的符號替換為直接引用,主要包含以下動作:
初始化(Initialization)
這時類加載過程的最后一步,這部分開始真正的執行Java代碼,也就是說,這個階段可以由程序員參與。
此階段其實就是執行類構造器?<clinit>()?方法的過程。
類加載器
類加載器(Class Loader)是Java虛擬機的一大創舉,它將“獲取類的二進制字節流”這個過程交給了開發人員自己去實現,只要編寫不同的Class Loader,應用程序本身就可以用相應的方式來獲取自己需要的類。
類與加載器的關系
對于任意一個類,都需要由加載它的類加載器和這個類本身一同確立其在虛擬機中的唯一性。
通俗的講,就是即便同一個Class文件,被不同的類加載器加載之后,得到也不是同一個“類”(equals方法返回false)。
雙親委派模型
從虛擬機角度講,只有兩種類加載器,一種是啟動類加載器(Bootstrap ClassLoader),在hotpot上使用C++實現,屬于虛擬機的一部分;另一種則是所有其他類的加載器,這些加載器是獨立于虛擬機的,由Java語言實現的,從開發者角度看,可以分為以下兩類:
擴展類加載器(Extension ClassLoader)
應用程序類加載器(Appliaction ClassLoader)
當然開發人員也可以自己編寫類加載器,最終不同的類加載器之間的層次關系如下圖所示:
這就是Java中著名的?雙親委派模型?,它要求除了頂級的BootStrap加載器之外,其他類加載器都必須有父類加載器,工作流程如下:
如果一個類加載器收到了類加載的請求,他首先不會自己去嘗試加載這個類,而是將這個請求委派給父類加載器去完成,只有當父加載器反饋自己無法完成加載請求時,子加載器才會自己去嘗試加載這個類。
這樣做的好處是,Java類隨著它的類加載器一起具備了一種帶有優先級的層次關系。舉個例子,比如?java.lang.Object?這個類,無論哪個類加載器加載時,最終都會委派給Bootstrap加載器去加載,這就保證了整個系統運行過程中的?Object?都是同一個類。
否則,如果用戶自己編寫了一個?java.lang.Object?類,并放在程序的classpath中,最終系統將會出現多個不同的Object類,整個Java體系就變得一團混亂了。
總結
以上是生活随笔為你收集整理的Java类加载机制总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SDUT 3379 数据结构实验之查找七
- 下一篇: Java selenium操作下拉滚动条