在前面兩篇部落格中我們簡單介紹了類載入器的基礎和類的生命週期的基礎內容,今天我們來繼續深入的來看一下java的類載入器的詳細內容。我們都知道。類載入器用來把類載入到java虛擬機器。從JDK2.0開始,類的載入過程採用父親委託機制。JVM的ClassLoader採用的是樹形結構,除了根類載入器以外,每個ClassLoader都會有且僅有一個父類載入器,使用者自訂的ClassLoader預設的父類載入器是系統類別載入器,當然你可以自己指定需要用個ClassLoader的執行個體,我們來看他們的父子關係:
父類委託機制中,當一個java程式請求載入器loader1載入Hello類時,loader1首先委託自己的父親載入器載入hello類,若父親載入器能載入,則由附加器完成載入人物,否則才由載入器loader1本身載入Hello類。下面我們來再次看一下java虛擬機器內建的幾個載入器:
除了java虛擬機器內建的載入器之外,我們使用者自己也可以自訂自己的類載入器,根據自己的需要。。Java提供了抽象類別java.lang.ClassLoder,所有使用者自訂的類載入器都要繼承這個classloader類。
註:載入器之間的父子關係實際上指的是載入器對象之間的封裝關係,而不是類之間的繼承關係。一對父子載入器可能是同一個載入器類的兩個執行個體,也可能不是。在子載入器對象中封裝了一個父載入器對象.當產生一個自訂的類載入器執行個體時,如果沒有指定它的父載入器,那麼系統類別載入器就將成為該類載入器的父載入器。如果在構造方法中指定父類載入器那麼父類載入器就是指定的載入器。證明如下:
ClassLoader loader1 = new MyClassLoader();//參數loader1將作為loader2的父載入器ClassLoader loader2 = new MyClassLoader(loader1);
當Java虛擬機器要載入一個類時,到底該派哪個類載入器去載入呢 ?我們看:
Loader1和loader2是我們自己定義的兩個類載入器,loader1和loader2是父子關係。現在我們想讓loader2這個類載入器載入我們自己寫的一個Sample類:loader2.loadclass(“sample”),我們來分析一下看看到底應該用哪一個類載入器去載入。當這段代碼被執行時,loader2首先到自己的命名空間去尋找Sample類是否已經被載入,如果被載入就直接返回這個類的class對象的引用。如果Sample類還沒有被載入,loader2首先請求loader1代為載入,loader1再請求系統類別載入器代為載入,系統類別載入器再請求擴充類載入器,擴充類載入器再請求根類載入器,若根類載入器和擴充類載入器都不能載入,則系統類別載入器嘗試載入,若能載入,則將Sample類所對應的Class對象的引用返回給loader1,loader1在將引用返回給loader2,從而成功將Sample類載入到虛擬機器。若系統類別載入器不能載入Sample類,則loader1嘗試載入Sample了哦,若loader1不能載入,則loader2嘗試,若所有的類載入都不能載入,則拋出ClassNotFoundException異常。
定義類載入器:如果某個類載入器能夠載入一個類,那麼該類載入器就稱作:定義類載入器;定義類載入器及其所有子載入器都稱作:初始類載入器
父委託機制的優點就是能夠提高軟體系統的安全性。因為在詞機制下,使用者自訂的類載入器不可能載入本應該由父載入器載入的可靠類,從而防止不可靠的惡意代碼代替由父類載入器載入的可靠類,從而防止不可靠的甚至惡意的代碼代替由父類載入器載入的可靠代碼。如,java.lang.Object類總是由根類載入器載入的,其他任何使用者自訂的類載入器都不可能載入含有惡意代碼的java.lang.Object類。
命名空間,其實這裡所說的命名空間就是我們java中常用的package,每個類載入器都有自己的命名空間,命名空間由該載入器及所有父載入器所載入的類的組成。在同一個命名空間中,不會出現類的完整名字(包括類的包名)相同的兩個雷;在不同的命名空間中,有可能會出現類的完整名字(包括類的包名)相同的兩個類。
由同一類載入器載入的屬於相同包的類組成了運行時包。決定兩個類是不是屬於同一個運行時包,不僅要看他們的包名稱是否相同,還要看定義類載入器是否相同。只有屬於同一運行時包的類之間才能相互訪問可見(預設存取層級)的類和成員。假設使用者自訂了一個類java.lang.TestCase並由用於自訂的類載入器載入,由於java.lang.TestCase和核心類庫java.lang.*由不同的類載入器載入,他們屬於不同的運行時包,所以java.lang.TestCase不能訪問核心庫java.lang包中的包可見成員。
參考資料:北京張龍老師免費培訓視頻《類載入器的父親委託機制深度詳解》
------------------------------------------------------------------------------------------------------------
《Java程式員由笨鳥到菜鳥》電子版書正式發布,歡迎大家下載
http://blog.csdn.net/csh624366188/article/details/7999247