ClassLoader即類加載器,負責將 .class 文件(可能在磁盤上, 也可能在網絡上) 加載到內存中, 併爲之生成對應的 java.lang.Class 對象,當 JVM 啓動時,會造成由三個類加載器組成的初始類加載器層次結構:bootstrap classloader ——> extension classloader ——> system classloaderjava
bootstrap classloader:引導(也稱爲原始)類加載器,它負責加載Java的核心類。這個加載器的是很是特殊的,它實際上不是 java.lang.ClassLoader的子類,而是由JVM自身實現的。能夠經過執行如下代碼來得到bootstrap classloader加載了那些核心類庫:
bootstrap
[java] view plaincopy網絡
URL[] urls =sun.misc.Launcher.getBootstrapClassPath().getURLs(); jvm
for(int i = 0 , i < urls.length ; i++){ url
System.out.println(urls[i].toExternalForm()); spa
} 操作系統
由於JVM在啓動的時候就自動加載它們,因此不須要在系統屬性CLASSPATH中指定這些類庫.net
extension classloader -擴展類加載器,它負責加載JRE的擴展目錄(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系統屬性指定的)中的JAR包。這爲引入除Java核心類之外的新功能提供了一個標準機制。由於默認的擴展目錄對全部從同一個JRE中啓動的JVM都是通用的,因此放入這個目錄的 JAR類包對全部的JVM和system classloader都是可見的。orm
extension classloader是system classloader的parent,而bootstrap classloader是extension classloader的parent,但 bootstrap classloader 不是一個實際的classloader。對象
system classloader - 系統(也稱爲應用)類加載器,它負責在JVM被啓動時,加載來自在命令java中的-classpath或者java.class.path系統屬性或者 CLASSPATH操做系統屬性所指定的JAR類包和類路徑。
能夠經過靜態方法ClassLoader.getSystemClassLoader()找到該類加載器。若是沒有特別指定,則用戶自定義的任何類加載器都將該類加載器做爲它的父加載器。
classloader 加載類用的是全盤負責委託機制。
全盤負責:便是當一個classloader加載一個Class的時候,這個Class所依賴的和引用的全部 Class也由這個classloader負責載入,除非是顯式的使用另一個classloader載入
委託機制:先讓parent(父)類加載器 (而不是super,它與parent classloader類不是繼承關係)尋找,只有在parent找不到的時候才從本身的類路徑中去尋找。
l類加載還採用了cache機制:若是 cache中保存了這個Class就直接返回它,若是沒有才從文件中讀取和轉換成Class,並存入cache,這就是爲何修改了Class可是必須從新啓動JVM才能生效的緣由。
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.