1 類載入機制概念是什麼?
JVM把描述類的資料從Class檔案載入到記憶體,並對資料進行校驗、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java型別。這就是類載入機制。
2 類位元組碼有哪幾部分內容組成?
Class檔案結構中只有兩種資料型別:
- 無符號數:屬於基本的資料型別,以u1、u2、u4、u8分別代表1、2、4、8個位元組的無符號數,可以用來描述數字、索引引用、數量值、或者按照UTF-8編碼的字串值;
- 表:由多個無符號數或者其他表作為資料項構成的複合資料型別,所有表都習慣以"_info"結尾;
- 所以,Class檔案本質上就是一張表;
Class檔案結構的內容組成:
- 魔數:每個Class檔案的前4個位元組,JAVA語言魔數:CAFEBABE,16進位制數,唯一左右就是確認檔案是否是一個被虛擬機器接受的Class檔案;
- Class檔案版本:Class檔案第5、6個位元組是次版本號,7、8個位元組是主版本號;
- 常量池:從第9個位元組開始,主要存放兩大類常量:(1)字面量;(2)符號引用;
- 訪問標誌:緊跟常量池之後的兩個位元組代表訪問標誌,代表類或介面的層次資訊;
- 類索引、父類索引與介面索引集合:緊跟訪問標誌之後的就是類索引、父類索引與介面索引,都是u2型別資料,Class檔案中由這三項資料來確定類的繼承關係;
- 欄位表集合:緊接著就是欄位表集合,用於描述介面或類中宣告的變數;
- 方法表集合:緊接著就是方法表集合,用於描述介面或類中宣告的方法;
3 類載入過程大體分為幾步?
4 什麼時機會出發類載入?
- 建立類的例項:使用new關鍵字例項化物件;
- 訪問類的靜態變數:getstatic或putstatic,讀取或設定一個類的靜態變數(不包括被final修飾的靜態變數);
- 訪問類的靜態方法:invokestatic呼叫一個類的靜態方法;
- 使用java.lang.reflect進行反射呼叫:如,Class.forName("xxxxx");
- 子類初始化時,會先初始化父類;
5 被動引用有幾種,被動引用不會觸發類初始化?
- 通過子類引用父類的靜態欄位,不會導致子類初始化,只會初始化父類;
- 通過陣列定義來引用類,不會觸發類的初始化;
- 常量在編譯階段會存入呼叫類的常量池中,本質上並沒有直接引用到定義常量的類,因為不會觸發定義常量的類初始化;
6 類載入:第一步載入階段具體過程?
- 通過類的全限定名稱獲取定義此類的二進位制流;
- 將二進位制流靜態結構轉化為方法區的執行時資料結構;
- 在記憶體中生成一個代表這個類的java.lang.Class物件。對於HotSpot虛擬機器,Class物件是存放在方法區裡的;
7 類載入:第二步驗證階段具體過程?
主要作用就是確保Class檔案的位元組流中包含的資訊符合當前虛擬機器的要求,並且不會危害虛擬機器自身安全;
- 檔案格式驗證:對檢查格式、版本;
- 後設資料驗證:對位元組碼進行語義分析;
- 位元組碼驗證;
- 符號引用驗證;
8 類載入:第三步準備階段具體過程?
- 正式為類變數分配記憶體,記憶體在方法區中進行分配,類變數是指static修飾的變數;
- 設定類變數的初始值,這個初始值通常情況下是資料型別的零值,如:public static int value = 123;初始值是0,不是123,賦值123動作會在初始化階段才會執行;
9 類載入:第四步解析階段具體過程?
將Class檔案的常量池內的符號引用替換為直接引用;
10 類載入:第五步初始化具體過程?
真正開始執行類中定義的Java程式程式碼,初始化過程就是執行類構造器()方法的過程;
- ()方法會自動收集類中所有類變數(static)的賦值動作和靜態程式碼塊,編譯器收集順序由程式碼出現順序決定;
- ()方法與類例項建構函式不同,虛擬機器會保證父類的()執行完畢後再執行子類的()方法;
12 類載入器有幾種,每種的作用?
- 根類載入器(Bootstrap ClassLoader):其負責載入Java的核心類,比如String、System這些類;
- 擴充類載入器(Extension ClassLoader):其負責載入JRE的擴充類庫;
- 系統類載入器(System ClassLoader):其負責載入CLASSPATH環境變數所指定的JAR包和類路徑;
- 使用者類載入器:使用者自定義的載入器,以類載入器為父類
13 類載入器雙親委託模式是什麼及為什麼?
雙親委派機制:如果一個類載入器在接到載入類的請求時,它首先不會自己嘗試去載入這個類,而是把這個請求任務委託給父類載入器去完成,依次遞迴,如果父類載入器可以完成類載入任務,就成功返回;只有父類載入器無法完成此載入任務時,才自己去載入。
Java類隨著載入它的類載入器一起具備了一種帶有優先順序的層次關係。比如,Java中的Object類,它存放在rt.jar之中,無論哪一個類載入器要載入這個類,最終都是委派給處於模型最頂端的啟動類載入器進行載入,因此Object在各種類載入環境中都是同一個類。如果不採用雙親委派模型,那麼由各個類載入器自己取載入的話,那麼系統中會存在多種不同的Object類。