Java虛擬機(二)------類的加載連接與初始化過程詳解

1Java程序對類的使用方式分爲兩種
——主動使用
——被動使用
2所有的Java虛擬機實現必須在每個類或接口被Java程序“首次主動使用”時才初始化他們

主動使用(7種)
應該從字節碼層面上去理解
1、創建類的實例(new 一個對象)
2、訪問某個類或者接口的靜態變量,或者對該靜態變量賦值
3、調用類的靜態方法
PS:助記符
訪問靜態變量getstatic
靜態變量賦值putstatic
調用類靜態方法invokestatic
4、反射。如(Class.forName(“com.test.Test”))
5、初始化一個類的子類
6、Java虛擬機啓動時被標明爲啓動類的類(Java Test),也就是包含main方法的類
7、Java1.7開始提供了 動態語言支持:
java.lang.invoke.MethodHandle實例的解析結果REF_getStatic,REF_putStatic,REF_invokeStatic句柄對應的類沒有初始化,則初始化???
不太明白

處理以上7中情況,其他都是被動加載

Java類的加載
類的加載指的是將類的.class文件的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在內存中創建一個java.lang.Class對象(規範並未說明Class對象位於哪裏,HotSpot虛擬機將其放在了方法區中)用來封裝在方法區內的數據結構
加載.class文件的方式
本地系統直接加載
通過網絡下載.class文件
從zip,jar等歸檔文件中加載.class文件
從專有數據庫中提取.class文件
將Java源文件動態編譯爲.class文件(動態代理的時候,jsp文件會被轉化成一個servlet,而servlet被編譯成一個class,會被虛擬機加載)
編寫代碼進行下驗證

package com.huawei.jvm.classloader;

public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyChild1.str);
    }
}
class MyParent1{
    public static String str = "hello world";
    static {
        System.out.println("Myparent1 static block");
    }
}
class MyChild1 extends MyParent1{
    //public static String str2 = ""
    static {
        System.out.println("Mychild1 static block");
    }
}

輸入內容爲 :
Myparent1 static block
hello world

package com.huawei.jvm.classloader;

public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyChild1.str2);
    }
}
class MyParent1{
    public static String str = "hello world";
    static {
        System.out.println("Myparent1 static block");
    }
}
class MyChild1 extends MyParent1{
    public static String str2 = "welcome";
    static {
        System.out.println("Mychild1 static block");
    }
}

輸入內容爲 :
Myparent1 static block
Mychild1 static block
welcome
原因是:對於靜態字段來說,只有直接定義了該字段的類纔會被初始化
第一個例子:str時被父類定義的,是對MyParent1的主動的使用,並沒有主動使用MyChild1
第二個例子:對MyChild1的主動使用,初始化一個子類的時候,父類也會被初始化。

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