首先介紹什么是類加載:
類加載就是java虛擬機(jī)將工程所需的Class文件中的二進(jìn)制數(shù)據(jù)到內(nèi)存中潜支,通過檢驗(yàn)蒸矛,解析娄徊,初始化等操作闽颇,將靜態(tài)的字節(jié)流轉(zhuǎn)化成方法區(qū)中動(dòng)態(tài)的數(shù)據(jù)結(jié)構(gòu)。
類的加載主要分為三個(gè)過程:加載寄锐、連接(驗(yàn)證兵多、準(zhǔn)備、解析)橄仆、初始化剩膘。
1、加載:主要是將Class文件中的二進(jìn)制數(shù)據(jù)讀到內(nèi)存中去盆顾,然后將其轉(zhuǎn)化為方法區(qū)中的運(yùn)行時(shí)數(shù)據(jù)(包括常量怠褐、靜態(tài)變量、靜態(tài)代碼塊)您宪,同時(shí)在堆中創(chuàng)建一個(gè)java.lang.Class對象奈懒,用于外部訪問這個(gè)Class類的入口。
2宪巨、連接:連接主要又分為三個(gè)階段磷杏,首先驗(yàn)證加載的類中的內(nèi)容是否符合正確的結(jié)構(gòu)、JVM的規(guī)范捏卓,其次準(zhǔn)備階段為類的靜態(tài)變量在方法區(qū)中分配內(nèi)存极祸,并賦初始值0或者null(這一點(diǎn)有一個(gè)問題注意就是static int a = 100 和 static final int a =100是不一樣的第一個(gè)a準(zhǔn)備階段的賦值是0,第二個(gè)a準(zhǔn)備階段賦值是100)怠晴,最后就是解析遥金,將二進(jìn)制數(shù)據(jù)中的符號(hào)引用轉(zhuǎn)化為直接引用。
3蒜田、初始化:初始化階段主要是對連接過程中的準(zhǔn)備階段賦初始值的靜態(tài)變量賦程序設(shè)定的初值稿械。初始化階段不是必須的,但是有幾種必須初始化類的情況:
當(dāng)new一個(gè)類時(shí)物邑、
使用getstatic或者putstatic讀取或者設(shè)置一個(gè)靜態(tài)變量時(shí)溜哮、
調(diào)用靜態(tài)方法、
對類進(jìn)行反射調(diào)用時(shí)色解、
初始化子類時(shí)首先初始化父類茂嗓、
當(dāng)子類調(diào)用父類的靜態(tài)字段時(shí)只需初始化父類。
這幾種情況下必須對類進(jìn)行初始化操作科阎。
這里區(qū)分一下“符號(hào)引用”和“直接引用”:
public class Test{
? public static void main() {
? ? String s=”adc”;
? ? System.out.println(“s=”+s);
? }
}
利用這段代碼來解釋就其中的代表“符號(hào)引用”的是s述吸,s是我們用來定義的一個(gè)String類型變量abc的符號(hào),這個(gè)符號(hào)在java程序中就代表著abc這個(gè)String類型變量。
這段代碼經(jīng)過jvm加載后就在計(jì)算機(jī)中就不需要s來代指abc這個(gè)String變量蝌矛,而是把s直接替換成abc的內(nèi)存地址道批。這里的內(nèi)存地址就稱之為直接引用。