Java類加載過程
一.類加載過程簡介
類的加載一般分為三個比較大的階段,分別是加載階段、連接階段和初始化階段。
1.加載階段
主要負責查找並且加載類的二進制數據文件,其實就是class文件
2.連接階段
連接階段所做的工作比較多,主要分為以下三個階段:
(1)驗證階段
主要是保證確保類的正確性,譬如class文件的版本,class文件的魔術因子是否正確。
(2)準備階段
為類的靜態變量分配內存,並且為其初始化默認值。
(3)解析階段
把類中的符號引用轉換成直接引用。
- 初始化階段
為類的靜態變量賦予正確的初始值也就是代碼編寫階段給定的值。
一.ClassLoader介紹
ClassLoader 的主要職責是負責加載各種class文件到JVM中,ClassLoader是一個抽象的class,給定一個class的二進制文件名,ClassLoader會嘗試加載並且在JVM中生成構成這個類的各個數據結構,然後使其分布在JVM對應的內存區域中。
二.類的主動使用和被動使用
JVM虛擬機規範規定,每個類或者接口被Java程序首次主動使用時才會對其進行初始化,但是不排除JVM在運行期間提前預判並且初始化某個類。
JVM同時規範了以下6中主動使用類的場景,具體如下:
(1)通過new關鍵字會導致類的初始化,並且是最終的初始化。
(2)訪問類的靜態變量,包括讀取和更新會導致類的初始化。
public class Simple {
static{
System.out.println("初始化");
}
public static int x = 10;
}
以上代碼中直接訪問變量x也會導致類的初始化。
(3)訪問類的靜態方法,會導致類的初始化。
public class Simple { static{ System.out.println("初始化"); } public static int x = 10;//靜態方法 public static void test(){ } }
以上代碼中直接調用test靜態方法也會導致類的初始化。
(4)對某個類進行反射操作,會導致類的初始化。
(5)初始化子類會導致父類的初始化,通過子類使用父類的靜態變量,只會導致父類的初始化,子類則不會被初始化。
(6)啟動類,也就是執行main函數所在的類會導致該類的初始化。
除了以上的6種情況,其余的都稱為被動使用,不會導致類的加載和初始化。
(1)構造某個類的數組時並不會導致該類的初始化。
Simple[] simples = new Simple[10]; System.out.println(simples.length);
(2)引用類的靜態常量不會導致類的初始化。
public final static int MAX = 100;
Java類加載過程