虛擬機器把描述類的資料從class檔案載入到記憶體,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的j**a型別(j**a位元組碼);
載入、連線(驗證、準備、解析)、初始化、使用、解除安裝;
有一篇部落格專門介紹過類的載入過程,這裡就不再詳細展開了,載入大致是通過類的全限定名獲取對應類的二進位制位元組流,然後將靜態的儲存結構轉換為執行時的動態儲存結構,生成乙個class物件,作為訪問這個類的方法的入口;連線過程包括驗證、準備、解析;驗證就是檢查位元組碼檔案是否符合虛擬機器的要求,比如是否是cafe babe開頭,檢查資料流和控制流是否符合規則,是否會危害虛擬機器的正常執行,符號引用對應的直接引用是否存在(是否能夠正常解析引用關係等等),初始化過程(clinit<>,不是每個類都必須存在,只是當有類靜態變數或者靜態**塊static時才會有),會按照**的順序收集靜態變數的賦值語句,進行賦值操作;使用過程不詳細贅述;類的解除安裝,判斷類是否可以解除安裝的條件比較苛刻,而且就算滿足了也不一定會解除安裝,(1)虛擬機器堆中不存在這個類的任何例項;(2)對應類的類載入器已經解除安裝;(3)不存在該類的clazz物件,保證無法在任何地方通過反射訪問到該類;
本篇文章重點梳理以下雙親委派模型和如何才能夠破壞雙親委派模型呢?
首先何為雙親委派模型呢?
從j**a程式設計師角度來看類載入器,包括三種型別:啟動類載入器(bootstrap classloader),負責載入j**a_home/lib下的基礎類;擴充套件類載入器,負責載入j**a_home/lib/ext下的相關類,系統類載入器(應用程式類載入器),如果沒有特殊指定類載入器,一般就是通過系統類載入器進行類的載入的;
除了啟動類載入器以外,任何類載入器都要有自己的父類載入器,當收到乙個類的載入請求的時候,先將類載入請求委託給父類載入器,只有當父類載入器無法完成載入的時候,才會由子類載入器去嘗試載入;
需要注意的是,這裡類載入器的父子關係是通過組合的形式來實現的,而不是通過繼承;
接下來通過源**來看一下雙親委派模型的原理:
private final classloader parent;整個邏輯就類似於注釋中寫的那樣,父類載入器不為空的情況下不斷向上傳遞,交給父類載入器去完成類的載入,只有當父類無法載入的情況下,才會去交給子類嘗試載入,而子類嘗試載入這個類使用的是public class> loadclass(string name) throws classnotfoundexception
protected class> loadclass(string name, boolean resolve) throws classnotfoundexception else
} catch (classnotfoundexception e)
}if (c == null)
}if (resolve)
}
findclass()方法,所以通常情況下,子類載入器只需要繼承classloader,然後重寫findclass方法就可以按照雙親委派模型的機制來完成類的載入了,父類載入不了自然會呼叫自己重寫的findclass方法來進行類的載入;
我們以乙個檔案系統類載入器為例,看下如何實現自定義的類載入器;
public class filesystemclassloader extends classloader最後,如果想要破壞雙親委派的類載入機制的話,需要怎麼做呢?protected class> findclass(string name) throws classnotfoundexception else
}// 從檔案中進行類的載入過程
public byte getclassdata(string classname)
return baos.tobytearray();
} catch (ioexception e)
return null;}}
通過分析原始碼我們發現,其實雙親委派的邏輯都是在loadclass()中實現的,如果我們想要破壞雙親委派模型,只需要讓自定義類載入器實現classloader類,然後重寫loadclass()方法,就可以不按照雙親委派的機制實現類的載入了!
類載入器及雙親委派機制
目錄類載入過程 3.初始化 類載入子系統中的initialization 類載入時機 類載入機制 引用資料 將類的class檔案讀入記憶體,並為建立乙個j a.lang.class物件。也就是說,當程式使用任何類時,系統都會為它新建乙個j a.lang.class物件。類的載入由類載入器完成,類載入...
談談類載入器的雙親委派機制
如果我們要載入乙個類,我們會先依據上圖的順序,一層一層去找是否已經有類載入器已經載入類資訊,最後才是我們的自己寫的類載入器,最大程度上防止資源的浪費 我們現在去看看classloader的原始碼 重點看看這段,簡單明瞭,他會先去看看classloader的parent extclassloader ...
雙親委派模型
從j a虛擬機器的角度來講,只存在兩種不同的類載入器 一種是啟動類載入器 bootstrap classloader 這個類載入器使用c 語言實現,是虛擬機器自身的一部分 另一種就是所有其他的類載入器,這些載入器都是由j a語言實現,獨立與虛擬機器外部,並且全部都繼承自j a.lang.classl...