類載入器自上而下的分為
bootstrap classloader -> ext classloader -> system classloader ->user defined classloader
除了bootstrap classloader在**層面無法獲得其引用外,其餘都可以通過classloader.getsystemclassloader()獲得系統class loader後通過getparent()獲得其父class loader. 其loadclass方法用來load對應的class,先判斷class loader的cache裡是否有對應的class,若沒有則先讓其父class loader嘗試load,若沒有父class loader則說明其父class loader為bootstrap classloader,若父class loader依然load不到,則呼叫findclass方法load,子類class loader可以繼承classloader類重寫findclass方法自定義類載入規則,當然也可以直接重寫loadclass方法打破父classloader控制的責任鏈。因此有必要介紹一下
thread.currentthread().getcontextclassloader(
),預設為system class loader,由launcher指定
這裡怎麼又出來乙個context classloader呢?它有什麼用呢?我們在建立乙個執行緒thread的時候,可以為這個執行緒通過setcontextclassloader方法來 指定乙個合適的classloader作為這個執行緒的context classloader,當此執行緒執行的時候,我們可以通過getcontextclassloader方法來獲得此context classloader,就可以用它來載入我們所需要的class。預設的是system classloader。利用這個特性,我們可以「打破」classloader委託機制了,父classloader可以獲得當前執行緒的context classloader,而這個context classloader可以是它的子classloader或者其他的classloader,那麼父classloader就可以從其獲得所需的 class,這就打破了只能向父classloader請求的限制了。這個機制可以滿足當我們的classpath是在執行時才確定,並由定製的 classloader載入的時候,由system classloader(即在jvm classpath中)載入的class可以通過context classloader獲得定製的classloader並加載入特定的class(通常是抽象類和介面,定製的classloader中是其實現),例 如web應用中的servlet就是用這種機制載入的.
如此以來有如下總結:
1. 對應不同的類載入器載入同乙個class檔案(類名,包名都想通),其可以在同乙個虛擬機器中,有兩個類
2. 為了防止第一種情況發生,需要使用父子類載入器責任鏈模式,任何類載入前先走父載入器
3. 可以採用urlclassloader並指明搜尋的classpath url,預設情況下其會用當前執行緒的contextclassloader作為其父classloader
4. 最後呼叫loadclass載入指明url中的類
github參考**
JVM 類載入器
載入 驗證 準備 解析 初始化 使用 解除安裝 jvm會在程式使用到某個類的時候通過類載入器將其載入jvm,當然是main方法開始的。驗證,根據j a的虛擬機器規範來校驗載入進來的 class檔案是否符合規範。準備,給類變數等分配一些記憶體空間及初始化值,各種各樣的零 解析,把符號引用替換為直接引用...
JVM 類載入機制 類載入器
類宣告週期 檔案格式驗證 基於二進位製流,只有這一步是基於二進位製流,後續步驟都是基於方法區資料 1.魔數 cafe babe 開頭 2.主次版本是否在當前jvm支援範圍 3.常量池的常量是否不被支援 4.很多很多規範 元資料驗證 1.類是否有父類,object 2.匪類是否繼承了被final修飾的...
JVM類載入機制 類載入器
一 概念 通過乙個類的全限定名來獲取描述此類的二進位制位元組流 實現這個動作的 模組成為 類載入器。4 雙親委派模型 1 定義 除了頂層的啟動類載入器外,其餘的類載入器都應當有自己的父類載入器,且載入器之間的父子關係一般不會繼承,而是使用組合關係來復用父載入器的 2 工作過程 如果乙個類載入器收到了...