JVM學習筆記5:類加載深入解析與階段分析

一、使用方式

1、主動使用

2、被動使用

所用的Java虛擬機實現必須在每個類或者接口被Java程序“首次主動使用”時,才初始化它們

二、主動使用

1、創建類的實例(new)

2、訪問某個類或者接口的靜態變量,或者對靜態賦值

3、調用類的靜態方法【2和3的本質是一樣的,getStatic、putStatic、invokeStatic 助記符】

4、反射(Class.forName("com.test.child"))

5、初始化一個類的子類

6、Java虛擬機啓動時被標記爲啓動類的類(包含main方法的類)

7、JDK 1.7開始提供動態語言支持

Java.lang.invoke.MethoHhandle實例的解析結果,沒有初始化,就去初始化。

* 其他都是被動使用,都不會導致類的初始化(第三個階段呦)

三、概念

1、類的加載:將類的.class 文件中的二進制數據讀入到內存中,將其放在運行時數據區的方法區內,然後在內存中創建一個java.lang.Class 對象(規範並未說明Class對象位於哪裏,HotSpot 虛擬機將其放在了方法區中)用來封裝類在方法區內的數據結構 

四、加載.class文件的方式

1、從本地系統中直接加載

2、通過網絡下載.class文件

3、從 zip、jar等歸檔文件中加載.class 文件

4、從轉悠數據庫提取.class文件(用的很少)

5、將Java源文件動態編譯爲.class文件(動態代理,運行期才生成)

jsp(html+Java)----》servelet(Java代碼)----》class文件

五、被動使用的例子:

package com.shengsiyuan.jvm.classloder;
/*
* 對於靜態字段,只有直接定義了該字段的類纔會初始化
* 即只初始化該靜態字段所在的類,當然包括他的父類,沒有子類
* 可以分別main函數中的兩行代碼,在一起運行兩行代碼,不一樣,因爲初始化僅初始話一次
* My Parent1 static block
  hello world
  My Child1 static block
  welcome
* */

public class MyTest1 {
    public static void main(String[] args) {
        System.out.println(MyChild1.str);//只有父類的被初始化。
        /*
           My Parent1 static block
           hello world
         */
        //System.out.println(MyChild1.str2);
        /*
        My Parent1 static block
        My Child1 static block
        welcome
         */
    }
}
//靜態代碼塊在加載的時候被執行
class Myparent1{
    public static String str ="hello world";
    static {
        System.out.println("My Parent1 static block");
    }

}
//初始化子類,父類一定被執行
class MyChild1 extends Myparent1{
    public static String str2 ="welcome";
    static {
        System.out.println("My Child1 static block");
    }
}


堅持

 

 

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