當(dāng)程序主動(dòng)使用某個(gè)類(lèi)時(shí),如果該類(lèi)還未被加載到內(nèi)存中,JVM會(huì)通過(guò)加載、連接、初始化3個(gè)步驟對(duì)該類(lèi)進(jìn)行類(lèi)加載。
1. 加載:加載指的是將類(lèi)的class文件讀入到內(nèi)存中,并為之創(chuàng)建一個(gè)java.lang.Class對(duì)象。 類(lèi)的加載由類(lèi)加載器完成,類(lèi)加載器由JVM提供,開(kāi)發(fā)者也可以通過(guò)繼承ClassLoader基類(lèi)來(lái)創(chuàng)建自己的類(lèi)加載器。 通過(guò)使用不同的類(lèi)加載器可以從不同來(lái)源加載類(lèi)的二進(jìn)制數(shù)據(jù),通常有如下幾種來(lái)源:
- 從本地文件系統(tǒng)加載
- 從jar包加載
- 通過(guò)網(wǎng)絡(luò)加載,把一個(gè)Java源文件動(dòng)態(tài)編譯,并執(zhí)行加載
2. 連接 當(dāng)類(lèi)被加載之后,系統(tǒng)為之生成一個(gè)對(duì)應(yīng)的Class對(duì)象,接著進(jìn)入連接階段,連接階段負(fù)責(zé)將類(lèi)的二進(jìn)制數(shù)據(jù)合并到JRE中。類(lèi)連接又可分為三個(gè)階段:
2.1 驗(yàn)證
- 文件格式驗(yàn)證
- 元數(shù)據(jù)驗(yàn)證
- 字節(jié)碼驗(yàn)證
- 符號(hào)引用驗(yàn)證
2.2 準(zhǔn)備 為類(lèi)的靜態(tài)變量分配內(nèi)存,并設(shè)置默認(rèn)初始值。
2.3 解析 將類(lèi)的二進(jìn)制數(shù)據(jù)中的符號(hào)引用替換成直接引用。
3. 初始化為類(lèi)的靜態(tài)變量賦予初始值。