Day1_Java進階_類加載器

2020.7.5 10:28:00

一、類加載基礎知識概述

  1. 類加載:當程序要使用某個類時,如果該類還未被加載到內存中,則系統會通過類的加載類的連接類的初始化這三個步驟來對類進行初始化。
    如果不出現意外的情況,JVM將會連續完成這三個步驟,所以有時也把這三個步驟統稱爲類加載或類初始化。

類的加載

  • 就是指將class文件讀入內存中,併爲之創建一個java.lang.Class對象。
  • 任何類被使用時,系統都會爲其創建一個java.lang.Class。

類的連接

  • 驗證階段:用於檢驗被加載的類是否有正確的內部結構,並和其他類協調一致。
  • 準備階段:負責爲類的類變量分配內存,並設置默認初始化值。
  • 解析階段:將類的二進制數據中的符號引用替換爲直接引用。

類的初始化:在該階段,主要是對類變量進行初始化。
類的初始化步驟:

  1. 若該類還未被加載和連接,則程序先加載並連接該類。
  2. 若該類的直接父類還未被初始化,則先初始化其直接父類。【先初始化父類再來初始化子類】
  3. 若類中有初始化語句,系統則會依次執行這些初始化語句。

【注意】:在執行第2個步驟時 ,系統對直接父類的初始化步驟也遵循初始化步驟1-3。
也就是說,直接父類還有父類的話,會繼續執行步驟2先去初始化父類的操作,以此類推,所有Java虛擬機最先初始化的總是java.lang.Object類[所有類的父類],當程序使用一個類時,系統會保證該類及其所有的父類都會被初始化。

類的初始化時機:Java程序首次通過以下幾種方式來使用某個類或者接口時,系統就會【初始化該類或接口】。
【首次】:一個類載入到Java虛擬機,同一個類將不會再次載入Java虛擬機了。

  • 創建類的實例
  • 調用類的類方法【調用該類的靜態方法時】
  • 訪問類或者接口的類變量,或者爲該類變量賦值
  • 使用反射的方式來強制創建某個類或接口對應的java.lang.Class對象
  • 初始化某個類的子類【首先會初始化父類】
  • 直接使用java.exe命令來運行某個主類時會初始化該類

二、類加載器

類加載器的作用: 負責將**.class文件**加載到內存中,併爲之生成對應的 java.lang.Class 對象。我們需要了解這個類加載機制,讓我們更好的理解程序的運行。

JVM的類加載機制:

  • 全盤負責:當一個類加載器負責加載某個Class類時,該Class所依賴的和引用其他Class也將該類加載器負責載入,除非顯示使用另外的一個類加載器來載入。
  • 父類委託:當類加載器負責加載某個Class類時,先讓父類加載器試圖加載該Class類,只有在父類加載器無法加載該類的時候,才試圖從自己的類路徑中加載該類。
  • 緩存機制:保證所有加載過的Class都會被緩存,當程序需要使用某個Class對象時,類加載器先從緩存區中搜索該Class,只有當緩存區中不存在該Class對象時,系統纔會去讀取該類對應的二進制數據,並將其轉換爲Class對象,然後存儲到緩存區中。

ClassLoader:是負責加載類的對象

Java運行時具有以下的內置類加載器

  • BootStrap Class Loader:它是虛擬機的內置類加載器,通常便是爲 null ,並且沒有父null
  • Platform Class Loader【或ExtClassLoader】:平臺類加載器可以看到所有平臺類,平臺類包括由平臺類加載器或祖先定義的Java SE平臺API,其是實現類和JDK特定的運行時類。
  • System Class Loader:它也被稱爲應用程序類加載器,與平臺類加載器不同,系統類加載器通常用於定義應用程序類路徑,模塊路徑和JDK特定工具上的類。
  • 類加載器的繼承關係:System的父加載器爲Platform,而Platform 的父加載器爲BootStrap【關鍵】

ClassLoader中有兩個方法:

  • static ClassLoader getSystemClassLoader():返回用於委派的系統類加載器。
  • ClassLoader getParent():返回父類加載器進行委派。
package com.hoqis;

/**
 * @author HoQis
 * @create 2020-07-06 10:10
 */
public class ClassLoaderDemo {
    public static void main(String[] args) {
        ClassLoader c1 = ClassLoader.getSystemClassLoader();
        System.out.println("返回用於委派的系統類加載器:"+c1);//AppClassLoader

        ClassLoader c2 = c1.getParent();
        System.out.println("返回父類加載器進行委派:"+c2);//ExtClassLoader

        ClassLoader c3 = c2.getParent();
        System.out.println("最後的父類:"+c3);//null
    }
}

打印結果:
"C:\Program Files\Java\jdk1.8.0_161\bin\java.exe" "-javaagent:D:\_Java\_Software\IntelliJ_IDEA\IntelliJ_IDEA_2019.2.4\IntelliJ_IDEA\IntelliJ IDEA 2019.2.4\lib\idea_rt.jar=7443:D:\_Java\_Software\IntelliJ_IDEA\IntelliJ_IDEA_2019.2.4\IntelliJ_IDEA\IntelliJ IDEA 2019.2.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_161\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_161\jre\lib\rt.jar;D:\_Java\_Software\IntelliJ_IDEA\IntelliJ_IDEA_2019.2.4\IntelliJ_IDEA_WorkSpace_0706\Reflect\out\production\Reflect" com.hoqis.ClassLoaderDemo
返回用於委派的系統類加載器:sun.misc.Launcher$AppClassLoader@18b4aac2
返回父類加載器進行委派:sun.misc.Launcher$ExtClassLoader@1540e19d
最後的父類:null

Process finished with exit code 0

2020.7.6 10:36:00 Complete!!!

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