過去總是喜歡看,但不怎麼做實驗,或者是實驗做了就仍了,也不記錄,結果導致:看了忘,忘了看。這回重讀《深入體驗Java_Web開發內幕-核心基礎》,恰好提到,順便記錄一下吧。
1. 簡單介紹
- Bootstrap、 ExtClassLoader、 AppClassLoader是java最根正苗紅的類加載器。
- Bootstrap是本地代碼編寫的(例如C), ExtClassLoader、 AppClassLoader是java代碼,且都在rt.jar中,且很巧的都是sun.misc.Launcher內部類(不過這個不是重點)。
- Bootstrap是爺爺、ExtClassLoader是爸爸、AppClassLoader是孩子(孫子)。但由於爸爸ExtClassLoader太忙了,所以照顧孩子AppClassLoader的責任就有爺爺Bootstrap來處理了(即,雖然ExtClassLoader是AppClassLoader老爸,但卻是由爺爺Bootstrap加載的AppClassLoader。該情況與中國國情完全一樣)。
2. 代碼實驗
public class LoaderTest {
/**
* @param args
*/
public static void main(String[] args) {
new LoaderTest().test();
}
/**
* @param args
*/
public void test() {
ClassLoader fatherLoader = this.getClass().getClassLoader();
System.out.println("當前類的父加載器名稱:" + fatherLoader.getClass().getName());
// 這是因爲AppClassLoader的父加載器雖然是ExtClassLoader,但是卻是Bootstrap
// 加載的(所以它的.getClassLoader()返回爲null)
// Bootstrap、 ExtClassLoader、 AppClassLoader的關係很符合中國過去,可以這麼描述:ExtClassLoader是AppClassLoader的爸爸,但是AppClassLoader確實他爺爺Bootstrap一把屎一把尿喂大的。
System.out.println("AppClassLoader的直接加載器是null嗎:"
+ (fatherLoader.getClass().getClassLoader() == null));
ClassLoader grandfatherLoader = fatherLoader.getParent();
System.out.println("爺爺載器名稱:" + grandfatherLoader.getClass().getName());
}
}
代碼運行結果:
AppClassLoader的加載器是null嗎:true
爺爺載器名稱:sun.misc.Launcher$ExtClassLoader
3. 類加載器各自搜索的目錄
1.Bootstrap Loader(啓動類加載器):加載System.getProperty("sun.boot.class.path")所指定的路徑或jar。通過System.out.println(System.getProperty("sun.boot.class.path"));打印,發現主要是“D:\Program Files\Java\jdk1.6.0_10\jre\lib”中的jar包。
2.Extended Loader(標準擴展類加載器ExtClassLoader):加載System.getProperty("java.ext.dirs")所指定的路徑或jar。在使用Java運行程序時,也可以指定其搜索路徑,例如:java -Djava.ext.dirs=d:\projects\testproj\classes HelloWorld。
通過打印System.out.println(System.getProperty("java.ext.dirs"));,可以發現主要加載目錄爲:
“D:\Program Files\Java\jdk1.6.0_10\jre\lib\ext;C:\WINDOWS\Sun\Java\lib\ext”
參考:
http://hi.baidu.com/haifengjava/blog/item/498fd8365ef5c8390a55a9db.html
http://lavasoft.blog.51cto.com/62575/184547
…………