java類加載

Java源程序在編譯後生成Class類文件,在類文件中存儲的各種信息最終都需要加載到虛擬機中之後才能被運行和使用。

虛擬機把描述類的數據從Class文件加載到內存,並對數據進行校驗、轉化解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。



加載 加載是類加載過程的第一個階段,在這個階段,虛擬機需要完成的功能主要有:(1)通過一個類的權限定名來獲取定義該類的二進制字節流(2)將這個字節流所代表的靜態存儲結構轉化爲方法區的運行時數據結構(3)在Java堆中生成一個代表該類的java.lang.Class對象,作爲方法區這些數據的訪問入口。

驗證(很重要但不是一定必要的階段)驗證是連接階段的第一步,這一階段的目的是爲了確保Class文件的字節流中包含的信息符合當前虛擬機的要求,並且不會危害虛擬機自身的安全。
比如說這個類是否有父類(Object就沒有父類)
比如說這個類是否繼承了不該繼承的父類(final類不可以繼承)
也就是檢查java語法,保證不存在不符合java語法的數據。


準備 準備階段是正式爲類變量分配內存並設置類變量初始值的階段,這些內存都將在方法區中進行分配。所謂類變量,就是被static關鍵字修飾的變量,不包括實例變量。給靜態變量賦0值。
Static Int value=32;
則給Value賦值爲0.

解析 解析階段是虛擬機將常量池內中的符號引用替換爲直接引用的過程。

符號引用:它是一個字符串。它給出了被引用的內容的名字並且可能會包含一些其他關於這個被引用項的信息--這些信息必須唯一地識別一個類、字段、方法。這樣,對於其他類的符號引用必須給出類的全名。對於其他類的字段,必須給出類名、字段名、字段描述符。對於其他類的方法的引用必須給出類名、方法名以及方法描述符。

直接引用:對於指向“類型”【Class對象】、類變量、類方法的直接引用可能是指向方法區的本地指針。

符號引用和虛擬機的內存佈局無關,符號引用的目標不一定加載到內存上了。
直接引用和虛擬機的內存佈局有關,所以直接引用的目標一定加載到內存中。
符號引用在不同的虛擬機上被翻譯出來的直接引用不同。

初始化 類初始化階段是類加載過程的最後一步,到了這一階段,才真正開始執行類中定義的Java程序代碼。
Static int value = 32;
則給value賦值爲32.

初始化的條件:
有且只有五種
New,調用靜態字段(final,因爲常量池的原因,沒有調用定義final的類,不會初始化),
調用靜態方法,通過反射調用的類,包含main的類,父類還沒有初始化,則先初始化父類。


類加載器

類加載過程的第一個階段是加載,它主要是根據類的權限定名來獲取類的二進制字節流。這個階段主要是通過類加載其完成的。

絕大部分Java程序都會使用到三種類加載器:啓動類加載器(Bootstrap ClassLoader)、擴展類加載器(Extension ClassLoader)、和應用程序類加載器(Application ClassLoader),當然我們還可以使用自定義的類加載。




啓動類加載器 啓動類加載器是C++語言實現的,是虛擬機自身的一部分,它負責加載JRE/lib/tr.jar中的類,或者被-Xbootclasspath參數指定的路徑中的能被虛擬機識別的類庫。
擴展類加載器 有Java語言實現,負責加載Java平臺中擴展功能的一些Jar包,包括jre/lib/ext/*.jar或者java.ext.dies系統變量指定目錄下的jar包。
應用程序類加載器 一般也稱爲系統類加載器,它負責加載用戶路徑中指定的jar包及目錄中class。
在上面的類加載器圖中,我們可以看到類加載器中存在一種層次關係,這是類加載起的雙親委派模型(Parents Delegation Model)。
雙親委派模型要求除了頂層的啓動類加載器外,其餘的類加載器都應該有自己的父類加載器。
這裏類加載器間的父子關係不是通過繼承來實現,而是使用組合關係來複用類加載器的代碼。

雙親委派模型的工作過程是:如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成。每個層次的類加載都是如此,因此所有的加載請求最終都應傳送給頂層的啓動類加載器中,只有父類加載器反饋自己無法完成這個請求時,子加載器纔會嘗試自己去加載。

雙親委派機制的意義在於,對於保證java程序的穩定運行很重要,比如類java.lang.Object,他存放在rt.jar之中,無論哪個類加載器要加載這個類,最終都是爲派給啓動類加載器去加載,因此Object類在程序的各種類加載環境中都是一個類。如果沒有雙親委派模型,由各個類加載器自行去加載的話,如果用戶自己寫了一個java.lang.Object的類,並放在程序的ClassPath中,那麼系統就會出現多個不同的Object類,很混亂。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章