這篇文章主要介紹“java虛擬機(jī)的類加載機(jī)制介紹”,在日常操作中,相信很多人在java虛擬機(jī)的類加載機(jī)制介紹問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java虛擬機(jī)的類加載機(jī)制介紹”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
10年積累的成都做網(wǎng)站、網(wǎng)站設(shè)計經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站設(shè)計后付款的網(wǎng)站建設(shè)流程,更有南昌縣免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
類加載的時機(jī)
說到類加載的時機(jī),就不得不提類加載的生命周期了,加載——驗證——準(zhǔn)備——解析——初始化——使用——卸載。七個階段。書中說解析和初始化的位置可以互換,是為了支持java語言的動態(tài)綁定導(dǎo)致的。這點我暫時不知道,不做研究先。
不過我們一起來探討下類加載什么情況下會立即觸發(fā)初始化呢。
java虛擬機(jī)規(guī)范中明確規(guī)定了五種情況必須立即對類進(jìn)行初始化:
遇到new、getstatic、putstatic或者invokestatic 這4條字節(jié)碼指令時,如果類沒有初始化,則會先觸發(fā)類進(jìn)行初始化。這4條指令對應(yīng)最常見的java代碼場景為:使用new關(guān)鍵字實例化對象的時候、讀取或者設(shè)置一個類的靜態(tài)變量(static final修飾的變量不算,因為在編譯期就把該變量放入常量池中了)、調(diào)用一個類的靜態(tài)方法。
使用java.lang.reflect包的方法對類進(jìn)行放射調(diào)用時,如果沒有初始化,會優(yōu)先初始化
初始化一個類的時候,如果發(fā)現(xiàn)其父類還沒有初始化,會優(yōu)先初始化其父類
當(dāng)虛擬機(jī)啟動時,用戶指定一個要執(zhí)行的主類(main()方法的類),會優(yōu)先初始化主類
如果java.lang.invoke.MethodHandle實例最后解析的結(jié)果REF_getstatic、REF_putstatic、ERF_invokestatic的方法句柄,且這個方法的句柄所對應(yīng)的類沒有初始化,則會優(yōu)先初始化。
以上的5中場景成為對一個類的主動引用,除此之外,所以引用類的方式都不會觸發(fā)初始化,成為被動引用。
下面看看代碼:
package chapter.Seven;
class SuperClass {
static{
System.out.println("SuperClass init");
}
public static int value=123;
public static final String NAME="QuellanAn";
}
class SubClass extends SuperClass {
static{
System.out.println("SubClass init");
}
}
public class NotInitialzation {
public static void main(String[] args){
System.out.println(SubClass.value);
}
}
main方法中調(diào)用“SubClass.value”,value是SuperClass的靜態(tài)變量。所以觸發(fā)了上面第一點,所以SuperClass類會被初始化。雖然是通過SubClass調(diào)用的,但是SubClass類沒有觸發(fā)上面5點的任何一點,所以不會進(jìn)行初始化。
結(jié)果:
SuperClass init123
在看一個,就改下main()方法,其他都不不變。
public class NotInitialzation { public static void main(String[] args){ System.out.println(SubClass.NAME); }}
同樣根據(jù)上面第一點,可以發(fā)現(xiàn),NAME是靜態(tài)常量,在編譯期(形成class文件的時候)就已經(jīng)存在常量池中了。所以SuperClass也是不會初始化的。
結(jié)果:
QuellanAn
上面的例子可以很好的看出什么時候?qū)@個類初始化了什么時候沒有。有且只有上面那5中情況才會對類型進(jìn)行初始化。
另外說一點,當(dāng)一個類在初始化時,要求其父類全部都已經(jīng)初始化了,但是在接口初始化時,并不要求父接口全部初始化,只需要在正真用到哪個父接口就初始化那個。
類加載的過程
類加載的過程分為7個階段,但重要的前面加載——驗證——準(zhǔn)備——解析——初始化前面5個。下面來依次的說明下。
加載
在加載階段,虛擬機(jī)需要完成以下3件事:
1. 通過一個類的全限定名來獲取定義此類的二進(jìn)制字節(jié)流。(全限定名:第一次聽到這個詞有點摸不著頭腦,網(wǎng)上查了一下,才知道是有點絕對路徑的意思,比如
Java類包的定名:com.linux.struct.sort.bubblesort,從最原始最上層的地方援引到具體的對象,這就是全限定名了)
2.將二進(jìn)制字節(jié)流中所代表的的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)運行時結(jié)構(gòu)。
3.在內(nèi)存中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)這個的類的各個數(shù)據(jù)的訪問入口。
驗證
驗證是連接階段的第一步,驗證的目的主要是為了確保class文件轉(zhuǎn)換成的二進(jìn)制文件流中包含的信息符合當(dāng)前虛擬機(jī)的要求。并且不會危害到虛擬機(jī)的安全。
驗證階段主要完成4個階段的驗證工作:文件格式檢驗、元數(shù)據(jù)校驗、字節(jié)碼校驗、符號引用校驗。
準(zhǔn)備
準(zhǔn)備階段,是正式為類的變量分配內(nèi)存空間并設(shè)置類變量初始值的階段。這些變量所使用內(nèi)存都將在方法區(qū)中分配。需要注意的是:這個階段今次進(jìn)行內(nèi)存分配的進(jìn)包含類變量,而不包含實例變量。實例變量將在對象實例化時隨著對象一起分配到j(luò)ava堆中。并且這里說的初始值“通常情況”下是數(shù)據(jù)類型的零值,比如:
public static int value=123;
在value準(zhǔn)備階段過后的初始值為0,而不是123.value值在初始化的時候才會被賦值成123.因為把value賦值為123的putstatic指令在初始化后才執(zhí)行。
解析
解析階段是虛擬機(jī)將常量池內(nèi)的符號引用替換成直接引用的過程。
初始化
初始化階段,執(zhí)行類構(gòu)造器<clinit>()方法。會進(jìn)行類變量的賦值和靜態(tài)語句塊(static{}快)的執(zhí)行。
到此,關(guān)于“java虛擬機(jī)的類加載機(jī)制介紹”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
文章標(biāo)題:java虛擬機(jī)的類加載機(jī)制介紹
文章路徑:http://jinyejixie.com/article44/ipiihe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、App開發(fā)、微信小程序、軟件開發(fā)、云服務(wù)器、網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)