更新時(shí)間:2023-07-14 來(lái)源:黑馬程序員 瀏覽量:
Java類(lèi)加載過(guò)程可以分為加載、驗(yàn)證、準(zhǔn)備、解析和初始化五個(gè)階段。下面我會(huì)詳細(xì)解釋每個(gè)階段,并給出相應(yīng)的代碼演示。
加載階段是將類(lèi)的字節(jié)碼文件加載到內(nèi)存中,并創(chuàng)建一個(gè)對(duì)應(yīng)的Class對(duì)象。加載階段由類(lèi)加載器(ClassLoader)完成。類(lèi)加載器根據(jù)類(lèi)的全限定名查找并讀取類(lèi)的字節(jié)碼文件,然后將其轉(zhuǎn)換為內(nèi)部數(shù)據(jù)結(jié)構(gòu),并創(chuàng)建一個(gè)Class對(duì)象來(lái)表示這個(gè)類(lèi)。
示例代碼:
Class<?> clazz = Class.forName("com.example.MyClass");
驗(yàn)證階段會(huì)對(duì)字節(jié)碼進(jìn)行驗(yàn)證,以確保其符合Java虛擬機(jī)規(guī)范。驗(yàn)證過(guò)程包括檢查字節(jié)碼的結(jié)構(gòu)、語(yǔ)義以及符號(hào)引用的合法性等。驗(yàn)證階段的目的是確保加載的類(lèi)能夠安全、正確地執(zhí)行。
準(zhǔn)備階段是為類(lèi)的靜態(tài)變量分配內(nèi)存空間,并設(shè)置默認(rèn)初始值。靜態(tài)變量屬于類(lèi)本身而不是對(duì)象,所以在準(zhǔn)備階段,虛擬機(jī)會(huì)為這些靜態(tài)變量分配內(nèi)存,并設(shè)置默認(rèn)值。
示例代碼:
public class MyClass { public static int myStaticVariable; }
解析階段將符號(hào)引用轉(zhuǎn)換為直接引用。在Java代碼中,使用符號(hào)引用來(lái)引用類(lèi)、字段、方法等,而直接引用是可以直接指向內(nèi)存中的數(shù)據(jù)結(jié)構(gòu)的指針或者偏移量。解析階段的主要目的是將符號(hào)引用解析為可直接使用的直接引用。
示例代碼:
public class MyClass { public static void myStaticMethod() { // 靜態(tài)方法的解析 } }
初始化階段是對(duì)類(lèi)的靜態(tài)變量進(jìn)行賦值和靜態(tài)代碼塊的執(zhí)行。在這個(gè)階段,虛擬機(jī)會(huì)按照程序員指定的順序執(zhí)行類(lèi)的靜態(tài)變量賦值和靜態(tài)代碼塊中的代碼。初始化階段是類(lèi)加載過(guò)程的最后一個(gè)階段,也是類(lèi)被真正使用之前的最后準(zhǔn)備工作。
示例代碼:
public class MyClass { public static int myStaticVariable = 10; static { System.out.println("Static block"); } }
這就是Java類(lèi)加載的過(guò)程,包括加載、驗(yàn)證、準(zhǔn)備、解析和初始化五個(gè)階段。注意,這些階段不一定嚴(yán)格按照順序執(zhí)行,有可能會(huì)交叉進(jìn)行。