JVM ClassLoader加載過程
1)三個類加載器:
bootstrap classloader - 引導(也稱為原始)類加載器,它負責加載Java的核心類。
extension classloader - 擴展類加載器,它負責加載JRE的擴展目錄中JAR的類包。
system classloader - 系統(也稱為應用)類加載器,加載應用程序的類。
bootstrap classloader不是一個真正的ClassLoader實例
2)獲取引導類加載器加載了哪些類:
URL[] urls=sun.misc.Launcher.getBootstrapClassPath().getURLs();
for (int i = 0; i < urls.length; i++) {
System.out.println(urls.toExternalForm());
}
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方法來實現自己的載入過程。