jvm-005(張龍老師jvm教程) 加載連接初始化過程詳解

jvm-005
一、java程序對類的使用方式
      1:主動使用
      2:被動使用
二、初始化
      所有的java虛擬機的實現,都是在類或接口的首次主動使用時才初始化他們。
三、主動使用的7中情況:
      1:創建類的實例,new關鍵詞;
      2:訪問類或接口的靜態變量,或者對靜態變量賦值;
      3:調用類的靜態方法;
      4:程序的啓動類所在的類;
      5:初始化一個類的子類時會引起父類的主動使用和初始化;
      6:反射,如Class.forName("com.cn.Test01");
      7:jdk1.7之後的動態語言支持也會引起類的初始化。
四、除了以上7中情況,其他使用方式都是對類的被動使用。
五、類的加載
      類的加載是將.class文件的二進制數據加載到內存中,並將其放在運行時數據區域的方法區中,並創建一個java.lang.Object對象(hotspot虛擬機將其放置在方法區中),用來封裝類的數據結構。
六、加載class文件的方式
      1、從本地系統中加載;
      2、從網絡中下載.class文件;
      3、從zip、war、jar包中加載;
      4、數據庫中加載.class文件;
      5、將java源文件動態代理編譯爲.class文件;
      6、由其他文件生成的,比如jsp文件。
七、代碼示例
      1、代碼1

public class TestCode02 {
    public static void main(String[] args) {
        System.out.println(Child.a);
    }
}
class Parent {
    public static String a = "parent str ==";
    static {
        System.out.println("parent init");
    }
}
class Child extends Parent {
    public static String n = "child str ==";
    static {
        System.out.println("child init");
    }
}

RES:

parent init
parent str ==

原因是對於靜態屬性或者靜態方法來說,只有直接定義了該靜態屬性或者方法的類,並且被調用的情況,纔會引起該類的初始化。

=============================分隔符============================
2、代碼2

public class TestCode02 {
    public static void main(String[] args) {
        System.out.println(Child.n);
    }
}
class Parent {
    public static String a = "parent str ==";
    static {
        System.out.println("parent init");
    }
}
class Child extends Parent {
    public static String n = "child str ==";
    static {
        System.out.println("child init");
    }
}

RES:

parent init
child init
child str ==

原因是,程序調用了Child的靜態屬性 n ,因此會因此Child的初始化,但是Child的父類會優先子類被初始化,初始化會調用靜態代碼塊的執行,因此先打印 parent init, 然後是子類的初始化 child init,然後是代碼的執行child str ==。

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