目錄類載入過程
3.初始化(類載入子系統中的initialization)
類載入時機
類載入機制
引用資料
將類的class檔案讀入記憶體,並為建立乙個j**a.lang.class物件。也就是說,當程式使用任何類時,系統都會為它新建乙個j**a.lang.class物件。
類的載入由類載入器完成,類載入器通常由jvm提供。開發者可以通過繼承classloader基類來建立自己的類載入器。
jvm規範允許系統預先載入某些類。
當類被載入之後,系統為之生成乙個對應的class物件,接著將會進入連線階段,連線階段負責把類的二進位制資料合併到jre中。類連線又可分為如下3個階段。
驗證階段用於檢驗被載入的類是否有正確的內部結構,並和其他類協調一致。這是對自身安全的一種保護。驗證階段是j**a非常重要的乙個階段,它會直接的保證應用是否會被惡意入侵的一道重要的防線,越是嚴謹的驗證機制越安全。驗證的目的在於確保class檔案的位元組流中包含資訊符合當前虛擬機器要求,不會危害虛擬機器自身安全。
其主要包括四種驗證,檔案格式驗證,元資料驗證,位元組碼驗證,符號引用驗證。
檔案格式驗證:主要驗證位元組流是否符合class檔案格式規範,並且能被當前的虛擬機器載入處理。例如:主,次版本號是否在當前虛擬機器處理的範圍之內。常量池中是否有不被支援的常量型別。指向常量的中的索引值是否存在不存在的常量或不符合型別的常量。
元資料驗證:對位元組碼描述的資訊進行語義的分析,分析是否符合j**a的語言語法的規範。
位元組碼驗證:最重要的驗證環節,分析資料流和控制,確定語義是合法的,符合邏輯的。主要的針對元資料驗證後對方法體的驗證。保證類方法在執行時不會有危害出現。
符號引用驗證:主要是針對符號引用轉換為直接引用的時候,是會延伸到第三解析階段,主要去確定訪問型別等涉及到引用的情況,主要是要保證引用一定會被訪問到,不會出現類等無法訪問的問題。
類準備階段負責為類的靜態變數分配記憶體,並設定預設初始值。
將類的二進位制資料中的符號引用替換成直接引用。
初始化是為類的靜態變數賦予正確的初始值。
準備階段和初始化階段看似有點矛盾,其實是不矛盾的,如果類中有語句:private static int a = 10,它的執行過程是這樣的,首先位元組碼檔案被載入到記憶體後,先進行鏈結的驗證這一步驟,驗證通過後準備階段,給a分配記憶體,因為變數a是static的,所以此時a等於int型別的預設初始值0,即a=0,然後到解析(後面在說),到初始化這一步驟時,才把a的真正的值10賦給a,此時a=10。
建立類的例項,也就是new乙個物件
訪問某個類或介面的靜態變數,或者對該靜態變數賦值
呼叫類的靜態方法
反射(class.forname("com.lyj.load"))
初始化乙個類的子類(會首先初始化子類的父類)
jvm啟動時標明的啟動類,即檔名和類名相同的那個類
所謂全盤負責,就是當乙個類載入器負責載入某個class時,該class所依賴和引用其他class也將由該類載入器負責載入,除非顯示使用另外乙個類載入器來載入。
所謂的雙親委派,則是先讓父類載入器試圖載入該class,只有在父類載入器無法載入該類時才嘗試從自己的類路徑中載入該類。通俗的講,就是某個特定的類載入器在接到載入類的請求時,首先將載入任務委託給父載入器,依次遞迴,如果父載入器可以完成類載入任務,就成功返回;只有父載入器無法完成此載入任務時,才自己去載入。
步驟:a.類載入器受到類載入的請求。
b.將這個請求向上委託給父類載入器完成,一直向上委託,直到啟動類載入器。
c.啟動載入器檢測是否能夠載入這個類,能載入就結束,使用當前的載入器;否則,通知子載入器進行載入。
d.重複步驟c。
快取機制將會保證所有載入過的class都會被快取,當程式中需要使用某個class時,類載入器先從快取區中搜尋該class,只有當快取區中不存在該class物件時,系統才會讀取該類對應的二進位制資料,並將其轉換成class物件,存入緩衝區中。這就是為很麼修改了class後,必須重新啟動jvm,程式所做的修改才會生效的原因。
類載入機制及雙親委派模型
虛擬機器把描述類的資料從class檔案載入到記憶體,並對資料進行校驗 轉換解析和初始化,最終形成可以被虛擬機器直接使用的j a型別 j a位元組碼 載入 連線 驗證 準備 解析 初始化 使用 解除安裝 有一篇部落格專門介紹過類的載入過程,這裡就不再詳細展開了,載入大致是通過類的全限定名獲取對應類的二...
談談類載入器的雙親委派機制
如果我們要載入乙個類,我們會先依據上圖的順序,一層一層去找是否已經有類載入器已經載入類資訊,最後才是我們的自己寫的類載入器,最大程度上防止資源的浪費 我們現在去看看classloader的原始碼 重點看看這段,簡單明瞭,他會先去看看classloader的parent extclassloader ...
jvm 類載入器及雙親委派模板篇
每乙個類都有乙個對應它的類載入器。系統中的 classloder 在協同工作的時候會預設使用 雙親委派模型 即在類載入的時候,系統會首先判斷當前類是否被載入過。已經被載入的類會直接返回,否則才會嘗試載入。載入的時候,首先會把該請求委派該父類載入器的 loadclass 處理,因此所有的請求最終都應該...