類加載中的屬性問題

類加載中的屬性問題

舉三個例子來說明:

要準備的代碼

package com.lhc.load;

public class SuperClass {
    static {
        System.out.println("SuperClass init");
    }
    public static int value = 123;
}


package com.lhc.load;

public class SubClass extends SuperClass{
    static {
        System.out.println("SubClass init");
    }
}

第一個例子

    @Test
    public void extendsTest(){
        System.out.println(SubClass.value);
    }
    
上述代碼運行之後,只會輸出“SuperClass init!",而不會輸出“SubClass init!".對於靜態字段,
只有直接定義這個字段的類纔會被初始化,因此通過其子類來引用父類中定義的靜態字段,只會觸發父類
的初始化而不會觸發子類的初始化。至於是否要觸發子類的加載和驗證,在虛擬機規範中並未明確規定,
這點取決於虛擬機的具體實現。對於Sun HotSpot虛擬機來說,可通過-XX:+TraceClassLoading參
數觀察到此操作會導致子類的加載。
第二個例子

    @Test
    public void arrayTest(){
        SuperClass[] array =  new SuperClass[10];
    }
    
上述代碼運行之後,沒有輸出“SuperClass init!",說明並沒有觸發類SuperClass的初始化階段。
第三個例子

    @Test
    public void constTest(){
        System.out.println(ConstClass.value);
    }
    
上述代碼運行之後,沒有輸出“ConstClass init!",這是因爲雖然在Java源碼中引用了ConstClass類中
的常量VALUE,但其實在編譯階段通過常量傳播優化,已經將此常量的值"HelloWorld"存儲到了測試主類的
常量池中,以後測試主類對常量ConstClass.VALUE的引用實際都被轉化爲測試主類對自身常量池的引用了。
也就是說,實際上測試主類的Class文件之中並沒有CostClass類的符號引用入口,這兩個類在編譯成
Class之後就不存在任何聯繫了。
發佈了78 篇原創文章 · 獲贊 22 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章