類加載器負責加載所有的類,系統為所有被載入內存中的類生成一個java.lang.Class實例。一旦一個類被載入JVM中,同一個類就不會被再次載入了?,F在的問題是怎么樣才算“同一個類”?正如一個對象有一個唯一的標識一樣,一個載入JVM的類也有一個唯一的標識。
同理,載入JVM的類也有一個唯一的標識,在java中,一個類用其全限定類名(包括包名和類名)作為標識。但在JVM中,一個類用其全限定類名和其類加載器作為其唯一的標識。因此,如果在pg包中,有一個名為Person的類,被類加載器KlassLoader的實例kl負載加載,則該Person類對應的Class對象在jvm中表示為(Person、pg、kl)。這意味著兩個類加載器加載的同名類:(Person、pg、kl)和(Person、pg、kl2)是不同的。它們所加載的類也是完全不同的,互不兼容。
當JVM啟動時,會形成由三個類加載器組成的初始類加載器層次結構:
Bootstrap ClassLoader:根類加載器。
Extension ClassLoader:擴展類加載器。
System ClassLoaser:系統類加載器。
Bootstrap ClassLoader,被稱為引導(也稱為原始或根)類加載器。它負責加載 Java的核心類。在Sun的JVM中,當執行java.exe的命令時使用-Xbootclasspath選項或使用-D選項指定sun.boot.class.path系統屬性值可以指定加載附加的類。
根類加載器非常特殊,它并不是java.lang.ClassLoader的子類,而是由JVM自身實現的。
Extension ClassLoader,被稱為擴展類加載器,它負責加載JRE的擴展目錄(JAVA_HOME/jre/lib/ext或由java.ext.dirs系統屬性指定的目錄)中的JAR的類包。
System ClassLoaser,被稱為系統(也稱為應用)類加載器,它負責在JVM啟動時,加載來自命令java中的-classpath選項或java.class.path系統屬性,或CLASSPATH環境變量所指定的JAR包和類路徑。
JVM的類加載機制主要有如下三種機制:
全盤負責:就是當一個類加載器負載加載某個Class時,該Class鎖依賴的和引用的其它Class也將由該類加載器負載載入,除非顯式使用另外一個類加載器來載入。
父類委托:就是先讓父類加載器試圖加載該Class,只有在父類加載器午法加載該類時才嘗試從自己的類路徑中加載該類。
緩存機制:緩存機制將會保證所有被類加載過的Class都會被緩存,當程序中需要使用某個Class時,類加載器先從緩存中搜尋該Class,只有緩存中不存在該Class對象時,系統才會重讀取該類對應的二進制數據,并將其轉換成Class對象,并存入cache。這就是為什么修改了Class后,程序必須重新啟動JVM,程序所作的修改才會生效的原因
新聞熱點
疑難解答