從萌新的角度理解Java類加載機制

類加載機制

本文主要是對java中類加載機制的入門級別文章,主要介紹類加載機制基本概念,以及類加載機制主要內容。本文按照結構組織如下:
1. 類加載機制是什麼
2. 類加載機制主要內容
3. 類加載機制一般用途

一丶類加載機制是什麼?

java程序從靜態文本到動態執行的過程
    java中的類加載機制,從字面意思就不難理解。就是描述class文件加載到jvm的主要過程,class文件是對java類的描述,加載java類的過程就是加載class文件的過程。
    類加載機制是圍繞ClassLoader這個核心類展開的,classLoader就是類加載機制中的核心類。classLoader有如下幾個主要的方法:

classLoader的核心方法.png
- defineClass:是將字節碼加載到JVM內存中,解析成Class對象的方法。
- findClass: 該方式解析指定路徑下的class文件生成Class對象的方法。一般defineClass方法和findClass是組合使用的,在findClass方法中依據指定路徑,獲取字節流,然後代用defineClass方法進行解析。
- resolveClass:解析繼承關係上的的父類,以及所引用的類,是一個遞歸解析的過程,在對象正真被實例化的時候,該方法被調用。
- loadClass:該方法是上述所有方法的一站式解決方案,也是JVM自帶類加載機制。如果調用loadClass方法加載類,是按照JVM默認的規則加載類,如果需要定製類加載器,則通過重寫上述的三個方法可以達到效果

二丶類加載機制的主要內容

1. 誰來負責class文件的加載

在java代碼中,每個定義的類都是由classloader加載進來的。JVM中的類加載器之間的關係組織結構和類的繼承關係有些相似,都是一層層的,一個類加載器有父加載器,父加載器下面有許多子加載器。JVM主要提供三層類加載器:

1.1 類加載器組織結構

  • 第一層:Bootstrap ClassLoader,這個類加載器,主要複雜加載JVM自身工作所需要的類。其他人都訪問不到這個類加載器,是一個相對獨立的類加載,其上沒有父加載器,也沒有子加載器
  • 第二層:ExtClassLoader,這類加載是應用層能夠訪問到的頂層類加載器,可以認爲其沒有父加載器,只有子加載器。其主要負責加System.getProperty(“java.ext.dirs”)目錄下的類。
    -第三層:AppClassLoader,這個類加載器就是我們最常接觸的類加載器,用來接在classpath路徑下類的加載器。其父加載器是ExtClassLoader.
    特別注意,從邏輯上可以定義第四層類加載器:
  • 第四層:自定義classLoader,該層不是JVM自帶的類加載器,而是我們自定義的類加載器,在整個類加載的組織結構中,可以理解爲第四層,其父加載器是AppClassLoader.
    類加載器的組織結構在熟悉類加載器組織結構後,我們還不能回答究竟是誰負責加載java類。在介紹完上級委託加載機制(雙親委託加載機制)後,就可以從衆多classLoader中找到合適的類加載器加載java類了。

1.2 上級委託加載機制

上級委託加載機制
圖中的類加載器1是類加載器2的父加載器,從上往下依次類推。
- 向上詢問:當我們使用類加載器4加載目標對象時,並不一定是類加載器4來負責該類的加載,類加載器4在確保目標類未被加載後,會將加載請求傳遞給其父加載器classloader3。classloader3會繼續重複和classloader4相同的工作,向其父加載器傳遞加載請求,加載請求最後被傳遞給頂層加載器classloader1.。在該過程中如果某層加載器發現該類已加載了,則結束加載過程,確保不重複加載。如果頂層加載機制受理了加載請求,此次加載過程就結束了。**這個過程,
- 向下委派 如果頂層加載機制不受理該次加載請求,其會將類加載請求按原路遣返,沿途加載器將會依次檢查是否受理該次類加載請求,最後由受理加載器加載目標類。

2.類加載過程

上級委託機制回答了是誰負責加載類的這個問題,閱讀完這一節後,就可以回答JVM加載類的一般過程了。
JVM加載類的階段
- 第一階段:該階段的主要工作是定義去哪兒找class文件,並且通過字節流的形式將class文件加載到內存中。
- 第二階段:該階段細分爲三個小階段
1. 字節碼驗證:類加載對加載的字節碼,要做許多驗證,確保class文件格式正確,行爲正確。
2. 類準備:在該階段準備描述類中字段,方法以及實現接口所需要的數據結構,
3. 解析:在這個階段類加載器會將類中引用的所有相關類都加載進去,並且這是一個遞歸的過程。
- 第三階段:初始化class對象,在這個階段靜態變量將初始化,靜態代碼塊也是在這個時候執行的。

三丶定製類加載器

瞭解類加載機制的基本原理後,我們可以看看類加載機制在實際開發中的一些用途
- 在自定義路徑下查找class類文件,當我們需要的class文件,不是在classpath路徑下時,就需要自己實現一個類加載器來加載指定路徑下的class文件。
- 對要加載的類做特殊的處理,在網絡傳輸類信息時,一般會對類的字節碼加密。在加載到JVM之前需要對類的字節碼解密後再按傳統方法加載,這個過程就可以通過自定義類加載器實現
- 類加載器一個比較常見的應用就是熱部署,檢查到已經加載的class文件已經修改的時候,重新加載這個類,以實現熱部署。

Reference

[1]深入分析javaWeb技術內幕,許令波,第二版
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章