類裝載器就是錄找類的字節(jié)碼文件并構(gòu)造出類的JVM內(nèi)部表示對(duì)象的組件,在JAVA中,類裝載器把一個(gè)類裝入JVM中,
需要如下步驟:
1、裝載:查找和導(dǎo)入Class文件 2、鏈接:執(zhí)行校驗(yàn),準(zhǔn)備和解析步驟 1)、校驗(yàn):檢查載入Class文件數(shù)據(jù)的正確性 2)、準(zhǔn)備:給類的靜態(tài)變量分配存儲(chǔ)空間。 3)、解析:將符號(hào)引用轉(zhuǎn)換成直接引用。 3、初始化:對(duì)類的靜態(tài)變量,靜態(tài)代碼塊執(zhí)行初始化操作。
類裝載工作有ClassLoader及其子類負(fù)責(zé),ClassLoader是一個(gè)運(yùn)行時(shí)系統(tǒng)組件,它負(fù)責(zé)在運(yùn)行時(shí)查找和裝入Class子節(jié)碼文件。
JVM在運(yùn)行時(shí)會(huì)產(chǎn)生3個(gè)ClassLoader:
1、根裝載器
根裝載器不是ClassLoader的子類,它由C++語言編寫,所以在JAVA中找不到它,它主要負(fù)責(zé)裝載JRE的核心類庫,如JRE目標(biāo)下的rt.jar、charsets.jar等
2、擴(kuò)展類裝載器(ExtClassLoader)
ExtClassLoader負(fù)責(zé)裝載JRE擴(kuò)展目錄ext中的JAR類包;
3、應(yīng)用類裝載器(AppClassLoader)
AppClassLoader負(fù)責(zé)裝載Classpath路徑下的類包;
根裝載器,擴(kuò)展類裝載器(ExtClassLoader),應(yīng)用類裝載器(AppClassLoader)之間存在父子關(guān)系,其中ExtClassLoader和AppClassLoader都是ClassLoader的子類;
根裝載器是ExtClassLoader的父裝載器
ExtClassLoader是AppClassLoader的父裝載器;默認(rèn)情況使用AppClassLoader裝載應(yīng)用程序的類;
示例
public static void main(String[] args) {
/*ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
HelloWorld helloWorld=(HelloWorld)ac.getBean("helloWorld");
helloWorld.say();*/
ClassLoader loader=Thread.currentThread().getContextClassLoader();
System.out.println(loader);
System.out.println(loader.getParent());
System.out.println(loader.getParent().getParent());
}
輸出結(jié)果: sun.misc.Launcher$AppClassLoader@659e0bfd sun.misc.Launcher$ExtClassLoader@6d06d69c null
說明: 1、當(dāng)前ClassLoader是AppClassLoader 2、父類ClassLoader是ExtClassLoader 3、父類的父類是根裝載器(JAVA中無法獲得它的句柄,所以僅返回null)
如何理解JVM裝載器的“全盤負(fù)責(zé)委托機(jī)制”?
“全盤負(fù)責(zé)”是指當(dāng)一個(gè)ClassLoader裝載一個(gè)類時(shí),除非顯式的使用另一個(gè)ClassLoader,該類所依賴及引用的類也由之個(gè)ClassLoader載入;
“委托機(jī)制”是指先委托父裝載器尋找目標(biāo)類,只有在找不到的情況下才從自己的類路徑中查找并裝載目標(biāo)類。






