一、什么是ClassLoader?
大家都知道,當(dāng)我們寫好一個(gè)Java程序之后,不是管是CS還是BS應(yīng)用,都是由若干個(gè).class文件組織而成的一個(gè)完整的Java應(yīng)用程序,當(dāng)程序在運(yùn)行時(shí),即會(huì)調(diào)用該程序的一個(gè)入口函數(shù)來調(diào)用系統(tǒng)的相關(guān)功能,而這些功能都被封裝在不同的class文件當(dāng)中,所以經(jīng)常要從這個(gè)class文件中要調(diào)用另外一個(gè)class文件中的方法,如果另外一個(gè)文件不存在的,則會(huì)引發(fā)系統(tǒng)異常。而程序在啟動(dòng)的時(shí)候,并不會(huì)一次性加載程序所要用的所有class文件,而是根據(jù)程序的需要,通過Java的類加載機(jī)制(ClassLoader)來動(dòng)態(tài)加載某個(gè)class文件到內(nèi)存當(dāng)中的,從而只有class文件被載入到了內(nèi)存之后,才能被其它c(diǎn)lass所引用。所以ClassLoader就是用來動(dòng)態(tài)加載class文件到內(nèi)存當(dāng)中用的。
二、Java默認(rèn)提供的三個(gè)ClassLoader
BootstrapClassLoader:稱為啟動(dòng)類加載器,是Java類加載層次中最頂層的類加載器,負(fù)責(zé)加載JDK中的核心類庫,如:rt.jar、resources.jar、charsets.jar等,可通過如下程序獲得該類加載器從哪些地方加載了相關(guān)的jar或class文件:
URL[] urls = sun.misc.Launcher.getBootstrapClassPath().getURLs();for(inti =0; i < urls.length; i++) {? ? ? System.out.println(urls[i].toExternalForm());? }
以下內(nèi)容是上述程序從本機(jī)JDK環(huán)境所獲得的結(jié)果:
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/resources.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/rt.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/sunrsasign.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/jsse.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/jce.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/lib/charsets.jar
file:/C:/Program%20Files/Java/jdk1.6.0_22/jre/classes/
其實(shí)上述結(jié)果也是通過查找sun.boot.class.path這個(gè)系統(tǒng)屬性所得知的。
System.out.println(System.getProperty("sun.boot.class.path"));
打印結(jié)果:C:\Program Files\Java\jdk1.6.0_22\jre\lib\resources.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\rt.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\sunrsasign.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\jce.jar;C:\Program Files\Java\jdk1.6.0_22\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.6.0_22\jre\classes
Extension ClassLoader:稱為擴(kuò)展類加載器,負(fù)責(zé)加載Java的擴(kuò)展類庫,默認(rèn)加載JAVA_HOME/jre/lib/ext/目下的所有jar。
App ClassLoader:稱為系統(tǒng)類加載器,負(fù)責(zé)加載應(yīng)用程序classpath目錄下的所有jar和class文件。
注意:除了Java默認(rèn)提供的三個(gè)ClassLoader之外,用戶還可以根據(jù)需要定義自已的ClassLoader,而這些自定義的ClassLoader都必須繼承自java.lang.ClassLoader類,也包括Java提供的另外二個(gè)ClassLoader(Extension ClassLoader和App ClassLoader)在內(nèi),但是Bootstrap ClassLoader不繼承自ClassLoader,因?yàn)樗皇且粋€(gè)普通的Java類,底層由C++編寫,已嵌入到了JVM內(nèi)核當(dāng)中,當(dāng)JVM啟動(dòng)后,Bootstrap ClassLoader也隨著啟動(dòng),負(fù)責(zé)加載完核心類庫后,并構(gòu)造Extension ClassLoader和App ClassLoader類加載器。