JAVA類:我是如何被ClassLoader加載到內存的

前言

之前看到阿里的一個面試題,JAVA類的雙親委派加載機制是什麼?有什麼好處?工作這麼久,還不知道一個JAVA類如何被加載到內存並運行起來的有點羞愧。不懂但是會搜索啊,這篇文章就這樣誕生了。本文主要總結了JAVA的類加載模型(classLoader),一個類的加載過程。

 

 

 

 

ClassLoaderr定義

 

我們用eclipse或idea編寫一個xxx.java文件,通過編譯器編譯成xxx.class文件,ClassLoader就是用來加載這些class文件到內存當中的。

 

三個默認ClassLoader

一、BootStrap ClassLoader:啓動類加載器,最頂層類加載器,負責加載JDK中的核心類庫,如:rt.jar、resources.jar、charsets.jar等。

二、Extension ClassLoader:擴展類加載器,負責加載Java的擴展類庫,默認加載JAVA_HOME/jre/lib/ext/目下的所有jar。

三、App ClassLoader:系統類加載器,負責加載應用程序classpath目錄下的所有jar。

除了Java默認提供的三個ClassLoader之外,用戶還可以根據需要定義自已的ClassLoader,而這些自定義的ClassLoader都必須繼承自java.lang.ClassLoader類(Extension ClassLoader和App ClassLoader也繼承ClassLoader類)、以及重寫父類的findClass方法,但是Bootstrap ClassLoader不繼承ClassLoader,因爲它不是一個普通的Java類,底層由C++編寫,已嵌入到了JVM內核當中,當JVM啓動後,Bootstrap ClassLoader也隨着啓動,負責加載完核心類庫後,並構造Extension ClassLoader和App ClassLoader類加載器。

    ClassLoader加載機制

ClassLoader使用的是雙親委派的加載機制,每個ClassLoader實例都有一個父類加載器的引用(不是繼承的關係,是一個包含的關係),虛擬機內置的類加載器(Bootstrap ClassLoader)本身沒有父類加載器,但可以用作其它ClassLoader實例的的父類加載器。當一個ClassLoader實例需要加載某個類時,先把這個任務委託給它的父類加載器,一層一層的往上拋(有點像拋異常,哈哈),首先由最頂層的類加載器Bootstrap ClassLoader試圖加載,如果沒加載到,則把任務轉交給Extension ClassLoader試圖加載,如果也沒加載到,則轉交給App ClassLoader 進行加載,如果它也沒有加載得到的話,則返回給委託的發起者,由它到指定的文件系統或網絡等URL中加載該類。如果它們都沒有加載到這個類時,則拋出ClassNotFoundException異常。否則將這個找到的類生成一個類的定義,並將它加載到內存當中,最後返回這個類在內存中的Class實例對象。下圖比較形象:

 

 

    Java類加載的步驟

裝載:把二進制形式的Java類型讀入Java虛擬機中。

連接:把裝載的二進制形式的類型數據合併到虛擬機的運行時狀態中去。

驗證:確保Java類型數據格式正確並且適合於Java虛擬機使用。

準備:負責爲該類型分配它所需內存。

解析:把常量池中的符號引用轉換爲直接引用。

初始化:爲類中的靜態變量變量賦適當的初始值,執行靜態代碼塊。

 

面試題

 

1、爲什麼要使用雙親委託模型?

 

因爲這樣可以避免重複加載,當父親已經加載了該類的時候,就沒有必要子ClassLoader再加載一次。從安全角度考慮,如果不使用這種委託模式,我們自己定義一個Map來動態替代java核心api中定義的類型,這樣會存在非常大的安全隱患,而雙親委託的方式,就可以避免這種情況,因爲Map在啓動時就被引導類加載器(Bootstrcp ClassLoader)加載,所以用戶自定義的ClassLoader永遠也無法加載一個自己寫的Map,除非你改變JDK中ClassLoader搜索類的默認算法。

 

2、JVM在搜索類的時候,又是如何判定兩個class是相同的呢?

 

JVM在判定兩個class是否相同時,不僅要判斷兩個類名是否相同,而且要判斷是否由同一個類加載器實例加載的。只有兩者同時滿足的情況下,JVM才認爲這兩個class是相同的。就算兩個class是同一份class字節碼,如果被兩個不同的ClassLoader實例所加載,JVM也會認爲它們是兩個不同的class。

微信掃碼關注公衆號:JAVA取經之旅

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章