一、使用方式
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");
}
}
堅持