天天看點

類加載器

類加載器

github:https://github.com/wangzhiwubigdata/god-of-bigdata

類加載器

任意一個類,都由加載它的類加載器和這個類本身一同确立其在 java 虛拟機中的唯一性,每一個類加載器,都有一個獨立的類名稱空間。

是以,比較兩個類是否“相等”,隻有在這兩個類是由同一個類加載器加載的前提下才有意義,否則,即使這兩個類來源于同一個 class 檔案,被同一個虛拟機加載,隻要加載它們的類加載器不同,那麼這兩個類就必定不相等。

這裡的“相等”,包括代表類的 class 對象的 equals() 方法、isinstance() 方法的傳回結果,也包括使用 instanceof 關鍵字做對象所屬關系判定等情況。

系統提供了 3 種類加載器:

啟動類加載器(bootstrap classloader): 負責将存放在 <code>&lt;java_home&gt;\lib</code> 目錄中的,并且能被虛拟機識别的(僅按照檔案名識别,如 rt.jar,名字不符合的類庫即使放在 lib 目錄中也不會被加載)類庫加載到虛拟機記憶體中。

擴充類加載器(extension classloader): 負責加載 <code>&lt;java_home&gt;\lib\ext</code> 目錄中的所有類庫,開發者可以直接使用擴充類加載器。

應用程式類加載器(application classloader): 由于這個類加載器是 classloader 中的 getsystemclassloader() 方法的傳回值,是以一般也稱它為“系統類加載器”。它負責加載使用者類路徑(classpath)上所指定的類庫,開發者可以直接使用這個類加載器,如果應用程式中沒有自定義過自己的類加載器,一般情況下這個就是程式中預設的類加載器。

當然,如果有必要,還可以加入自己定義的類加載器。

雙親委派模型是描述類加載器之間的層次關系。它要求除了頂層的啟動類加載器外,其餘的類加載器都應當有自己的父類加載器。(父子關系一般不會以繼承的關系實作,而是以組合關系來複用父加載器的代碼)

如果一個類加載器收到了類加載的請求,它首先不會自己去嘗試加載這個類,而是把這個請求委派給父類加載器去完成,每一個層次的類加載器都是如此,是以所有的加載請求最終都應該傳送到頂層的啟動類加載器中,隻有當父加載器回報自己無法完成這個加載請求(找不到所需的類)時,子加載器才會嘗試自己去加載。

在 java.lang.classloader 中的 loadclass() 方法中實作該過程。

像 java.lang.object 這些存放在 rt.jar 中的類,無論使用哪個類加載器加載,最終都會委派給最頂端的啟動類加載器加載,進而使得不同加載器加載的 object 類都是同一個。

相反,如果沒有使用雙親委派模型,由各個類加載器自行去加載的話,如果使用者自己編寫了一個稱為 java.lang.object 的類,并放在 classpath 下,那麼系統将會出現多個不同的 object 類,java 類型體系中最基礎的行為也就無法保證。

(完)