前言:本博客內容由張孝祥Java高新技術整理而來
java虛擬機中可以安裝多個類加載器,系統默認三個主要的類加載器,每個類負責加載特定位置的類:BootStrap,ExtClassLoader,AppClassLoader。
類加載器也是java類,因爲其他事java類加載器本身也要被類加載器加載,顯然必須有第一個類加載器不是java類,這正是BootStrap。
java虛擬機中的所有雷莊在其採用具有父子關係的樹形結構進行組織,在實例化每個類裝載器對象時,需要爲其制定一個父級類裝載器或者默認採用系統類裝載器爲其父級類加載。
首先是一個實例,這個例子將本身這個類的加載器名稱和其父類加載器名稱打印了出來
package com.dao.chu.movie;
public class ClassLoaderTest {
public static void main(String[] args) {
ClassLoader classLoader = ClassLoaderTest.class.getClassLoader();
while (null != classLoader) {
System.out.println(classLoader.getClass().getName());
classLoader = classLoader.getParent();
}
}
}
輸出結果:
sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$ExtClassLoader
其中根加載器爲null也就是BootStrap
下面是類加載器之間的父子關係和管轄範圍圖:
下面我們將ClassLoaderTest這個類導出一個jar包到jre的ext目錄下
注意:如果直接導出有權限錯誤問題,可先導出到其他目錄,在拷貝到jre下
我們再次運行剛纔的代碼
運行結果:
sun.misc.Launcher$ExtClassLoader
只有ExtClassLoader加載了,證明了ExtClassLoader的管轄範圍,並且類加載是先從父加載器加載,加載不到纔會到子加載器加載。
類加載器的委託機制
首先當前線程的類加載器去加載線程中的第一個類。
如果類A中引用了類B,java虛擬機將使用加載類A的類加載器加載類B。還可以直接調用ClassLoader.loadClass()方法來指定某個類加載器去加載某個類。
每個類加載器加載類時,又先委託給其上級類加載器。
當所有祖宗類加載器沒有加載到淚,回到發起者加載器,還加載不到則拋出ClassNotFoundException,而不是再去找發起者的兒子類。