Posted on 2016-03-16 15:40
Milo的海域 閱讀(315)
評論(0) 編輯 收藏 所屬分類:
Java
1. 默認的3個classloader: BootstrapClassloader (Native實現), ExtClassloader, AppClassloader (Java實現)
2. 3個加載器并不是真正的父子繼承關系,而是邏輯上的,JVM啟動先創(chuàng)建ExtClassloader instance,然后構造AppClassloader的時候傳入ExtClassloader實例作為parent
Launcher.ExtClassLoader extcl;
try {
extcl = Launcher.ExtClassLoader.getExtClassLoader();
} catch (IOException var10) {
throw new InternalError("Could not create extension class loader", var10);
}
try {
this.loader = Launcher.AppClassLoader.getAppClassLoader(extcl);
} catch (IOException var9) {
throw new InternalError("Could not create application class loader", var9);
}
關于雙親委派原理: 在加載類的時候,會看看parent有沒有設定,如果設定了 就調用parent.loadClass方法,如果沒設定(==null)也就是parent應該是BootstrapClassloader, 會調用native的findBootstrapClass來加載類,代碼:
try {
if(this.parent != null) {
c = this.parent.loadClass(name, false);
} else {
c = this.findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException var10) {
;
}
目的是按照一定優(yōu)先級別裝載系統(tǒng)的lib,系統(tǒng)ext目錄的lib,以及classpath的lib,防止系統(tǒng)的默認行為或者類的實現被修改。
3. java 類的動態(tài)加載
Java內置的ClassLoader總會在加載一個Class之前檢查這個Class是否已經被加載過,已經被加載過的Class不會加載第二次。因此要想重新加載Class,我們需要實現自己的ClassLoader。
另外一個問題是,每個被加載的Class都需要被鏈接(link),這是通過執(zhí)行ClassLoader.resolve()來實現的,這個方法是 final的,因此無法重寫。Resove()方法不允許一個ClassLoader實例link一個Class兩次,因此,當你需要重新加載一個 Class的時候,你需要重新New一個你自己的ClassLoader實例。