加班使我快樂!
點贊再看,養成習慣!
開始之前,先來兩張圖冷靜一下。
類加載機制流程圖
java程序的執行流程圖
一、類加載機制的概念
二、類加載的生命週期
在類加載的過程中,加載、驗證、準備和初始化這四個階段發生的順序是確定的,而解析階段則不一定,他在某些情況下可以在初始化階段之後開始,這是爲了支持java語言的運行時綁定。
類初始化的時機:
- 創建類的實例
- 調用某個類的類方法(靜態方法)
- 訪問某個類或接口的類變量,或爲該類變量賦值
- 使用反射方式來強制創建某個類或接口對應的java.lang.class對象
- 初始化某個類的子類
- 直接使用java.exe命令來運行某個主類
三、類加載器的層次關係
-
啓動類加載器:它使用C++實現(這裏僅限於Hotspot,也就是JDK1.5之後默認的虛擬機,有很多其他的虛擬機是用Java語言實現的),是虛擬機自身的一部分。
-
所有其他的類加載器:這些類加載器都由Java語言實現,獨立於虛擬機之外,並且全部繼承自抽象類java.lang.ClassLoader,這些類加載器需要由啓動類加載器加載到內存中之後才能去加載其他的類。
-
啓動類加載器:Bootstrap ClassLoader,跟上面相同。它負責加載存放在JDK\jre\lib(JDK代表JDK的安裝目錄,下同)下,或被-Xbootclasspath參數指定的路徑中的,並且能被虛擬機識別的類庫(如rt.jar,所有的java.*開頭的類均被Bootstrap ClassLoader加載)。啓動類加載器是無法被Java程序直接引用的。
-
擴展類加載器:Extension ClassLoader,該加載器由sun.misc.Launcher$ExtClassLoader實現,它負責加載JDK\jre\lib\ext目錄中,或者由java.ext.dirs系統變量指定的路徑中的所有類庫(如javax.*開頭的類),開發者可以直接使用擴展類加載器。
-
應用程序類加載器:Application ClassLoader,該類加載器由sun.misc.Launcher$AppClassLoader來實現,它負責加載用戶類路徑(ClassPath)所指定的類,開發者可以直接使用該類加載器,如果應用程序中沒有自定義過自己的類加載器,一般情況下這個就是程序中默認的類加載器。
這種層次關係叫做類加載器的雙親委派模型。每一層上面的類加載器叫做當前層類加載器的父加載器,但是他們之間的父子關係不是由繼承來實現的,而是通過組合關係來複用父加載器中的代碼。
工作流程:一個類加載器收到了類加載的請求後,他會把請求委託給父加載器去完成,依次向上,因此,所有的類加載請求最終都應該被傳遞的頂層的啓動類加載器中(從底向上檢查類是否被加載),如果在父加載器中沒有找到所需的類,子加載器纔會嘗試自己去加載類(從頂向下加載類)。
四、一道面試題
能不能寫一個類叫java.lang.System?
答案:不可以。我們不能寫以“java.”開頭的類,因爲它要麼不能加載進內存,要麼即使你是用自定義的類去強行加載,也會收到一個SecurityException.
原文鏈接:https://blog.csdn.net/tang9140/article/details/42738433