1)三個類加載器:
bootstrap classloader - 引導(也稱為原始)類加載器,它負責加載Java的核心類。
extension classloader - 擴充類加載器,它負責加載JRE的擴充目錄中JAR的類包。
system classloader - 系統(也稱為應用)類加載器,加載應用程式的類。
bootstrap classloader不是一個真正的ClassLoader執行個體
JVM在運作時會産生三個ClassLoader:Bootstrap ClassLoader、Extension ClassLoader和AppClassLoader
AppClassLoader的Parent是ExtClassLoader,而ExtClassLoader的Parent為Bootstrap ClassLoader
2)擷取引導類加載器加載了哪些類:
URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (int i = 0; i < urls.length; i++) {
System.out.println(urls[i].toExternalForm());
}
在jre1.5中,該段輸出:
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/resources.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/rt.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/sunrsasign.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/jsse.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/jce.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/lib/charsets.jar
file:/D:/Program%20Files/Java/jdk1.6.0_14/jre/classes
即為所加載的java的核心類
3)擷取應用類加載器:
ClassLoader.getSystemClassLoader()
4)JVM類加載機制:全盤負責委托機制
全盤負責:當一個classloader加載一個Class的時候,這個Class所依賴的和引用的所有Class也由這個classloader負責載入,除非是顯式的使用另外一個classloader載入;
委托機制:先讓parent(父)類加載器(而不是super,它與parent classloader類不是繼承關系)尋找,隻有在parent找不到的時候才從自己的類路徑中去尋找。
Cache機制:如果cache中儲存了這個Class就直接傳回它,如果沒有才從檔案中讀取和轉換成Class,并存入cache,這就是為什麼我們修改了Class但是必須重新啟動JVM才能生效的原因。
5)每個ClassLoader加載Class的過程是:
1.檢測此Class是否載入過(即在cache中是否有此Class),如果有到8,如果沒有到2
2.如果parent classloader不存在(沒有parent,那parent一定是bootstrap classloader了),到4
3.請求parent classloader載入,如果成功到8,不成功到5
4.請求jvm從bootstrap classloader中載入,如果成功到8
5.尋找Class檔案(從與此classloader相關的類路徑中尋找)。如果找不到則到7.
6.從檔案中載入Class,到8.
7.抛出ClassNotFoundException.
8.傳回Class.
其中5.6步我們可以通過覆寫ClassLoader的findClass方法來實作自己的載入政策。甚至覆寫loadClass方法來實作自己的載入過程。