首頁 > 軟體

Java 類載入過程與類載入器詳細介紹

2022-07-31 10:00:08

1. 類載入過程

載入

通過類的全限定名(包名 + 類名),獲取到類的.class檔案,載入到元空間。

連結

  • 驗證:檢驗.class檔案的安全性
  • 準備:為靜態型別變數分配記憶體並設定預設值
  • 解析:將常數池內的符號參照轉換為直接參照,符號參照指向一個未被載入的類,或者未被載入類的欄位或方法,那麼解析將觸發這個類的載入

初始化

執行類的構造器方法init()的過程,若該類具有父類別,jvm會保證父類別的init先執行,然後在執行子類的init

2. 類載入器

啟動類載入器

啟動類載入器是由C/C++語言實現的,用來載入Java核心類庫。啟動類只載入包名為:java、javax、sun開頭的類

擴充套件類載入器

父類別載入器為啟動類載入器載入以下兩個目錄中的類庫:

  • java.ext.dirs目錄
  • JDK安裝目錄:jre/lib/ext目錄

我們就可以將我們自己的包放在以上目錄下,就會自動載入進來了。

應用類載入器

父類別載入器為啟動類載入器,負責載入環境變數classpath或者系統屬性java.class.path指定路徑下的類庫,是程式中預設的類載入器,我們Java程式中的類,都是由它載入完成的。

自定義類載入器

繼承java.lang.ClassLoader類,重寫findClass()方法 。如果沒有太複雜的需求,可以直接繼承URLClassLoader類,重寫loadClass方法。

作用

  • 加密:Java程式碼可以輕易的被反編譯,如果你需要把自己的程式碼進行加密以防止反編譯,可以先將編譯後的程式碼用某種加密演演算法加密,類加密後就不能再用Java的ClassLoader去載入類了,這時就需要自定義ClassLoader在載入類的時候先解密類,然後再載入。
  • 從非標準的來源載入程式碼:如果你的位元組碼是放在資料庫、甚至是在雲端,就可以自定義類載入器,從指定的來源載入類。

雙親委派模型

jvm對class檔案採用的是按需載入的方式,當需要使用該類時,jvm才會將它的class檔案載入到記憶體中產生class物件。在載入類的時候,是採用的雙親委派機制

  • 如果一個類載入器接收到了類載入的請求,它自己不會先去載入,會把這個請求委託給父類別載入器去執行。
  • 如果父類別還存在父類別載入器,則繼續向上委託,一直委託到啟動類載入器:Bootstrap ClassLoader
  • 如果父類別載入器可以完成載入任務,就返回成功結果,如果父類別載入失敗,就由子類自己去嘗試載入,如果子類載入失敗就會丟擲ClassNotFoundException異常,這就是雙親委派模式

打破雙親委派模型

用途:

  • Java應用中存在著很多服務提供者介面(Service Provider Interface,SPI),這些介面允許第三方為它們提供實現,如常見的 SPI 有 JDBC、JNDI等,這些 SPI 的介面屬於 Java 核心庫,一般存在rt.jar包中,由Bootstrap類載入器載入。而Bootstrap類載入器無法直接載入SPI的實現類,所以需要反向委派給其他類載入器進行載入
  • 在Tomcat伺服器中,存在一個伺服器執行多個不同版本但同名服務的需求,所以需要打破雙親委派模型,載入多個同名類。

方法:

  • 使用上下文類載入器
  • 重寫loadClass方法

到此這篇關於Java 類載入過程與類載入器詳細介紹的文章就介紹到這了,更多相關Java 類載入 內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com