1. 程式人生 > >類載入機制:全盤負責和雙親委託

類載入機制:全盤負責和雙親委託

“全盤負責”是指當一個ClassLoader裝載一個類時,除非顯示地使用另一個ClassLoader,則該類所依賴及引用的類也由這個CladdLoader載入。

例如,系統類載入器AppClassLoader載入入口類(含有main方法的類)時,會把main方法所依賴的類及引用的類也載入,依此類推。“全盤負責”機制也可稱為當前類載入器負責機制。顯然,入口類所依賴的類及引用的類的當前類載入器就是入口類的類載入器。

以上步驟只是呼叫了ClassLoader.loadClass(name)方法,並沒有真正定義類。真正載入class位元組碼檔案生成Class物件由“雙親委派”機制完成。

“雙親委派”是指子類載入器如果沒有載入過該目標類,就先委託父類載入器載入該目標類,只有在父類載入器找不到位元組碼檔案的情況下才從自己的類路徑中查詢並裝載目標類。

“雙親委派”機制載入Class的具體過程是:

  1. 源ClassLoader先判斷該Class是否已載入,如果已載入,則返回Class物件;如果沒有則委託給父類載入器。
  2. 父類載入器判斷是否載入過該Class,如果已載入,則返回Class物件;如果沒有則委託給祖父類載入器。
  3. 依此類推,直到始祖類載入器(引用類載入器)。
  4. 始祖類載入器判斷是否載入過該Class,如果已載入,則返回Class物件;如果沒有則嘗試從其對應的類路徑下尋找class位元組碼檔案並載入。如果載入成功,則返回Class物件;如果載入失敗,則委託給始祖類載入器的子類載入器。
  5. 始祖類載入器的子類載入器嘗試從其對應的類路徑下尋找class位元組碼檔案並載入。如果載入成功,則返回Class物件;如果載入失敗,則委託給始祖類載入器的孫類載入器。
  6. 依此類推,直到源ClassLoader。
  7. 源ClassLoader嘗試從其對應的類路徑下尋找class位元組碼檔案並載入。如果載入成功,則返回Class物件;如果載入失敗,源ClassLoader不會再委託其子類載入器,而是丟擲異常。

“雙親委派”機制只是Java推薦的機制,並不是強制的機制。

我們可以繼承java.lang.ClassLoader類,實現自己的類載入器。如果想保持雙親委派模型,就應該重寫findClass(name)方法;如果想破壞雙親委派模型,可以重寫loadClass(name)方法。