小編給大家分享一下jvm類加載的過程可分為哪三步,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
jvm類加載的過程分為三步:加載、連接和初始化。
加載
通過類的全路徑將這個類從外部加載到j(luò)vm中,同時在方法區(qū)生成該類的描述信息并在內(nèi)存生成該類的Claas類型。作為方法區(qū)這個類的數(shù)據(jù)訪問入口。
連接
這是很重要的一步,過程比較復(fù)雜,分為三步:驗證、準(zhǔn)備和解析。
驗證:確保類加載的正確性。一般情況由javac編譯的class文件是不會有問題的,但是可能有人的class文件是自己通過其他方式編譯出來的,這就很有可能不符合jvm的編 譯規(guī)則,這一步就是要過濾掉這部分不合法文件
準(zhǔn)備:為類的靜態(tài)變量分配內(nèi)存,將其初始化為默認(rèn)值 。我們都知道靜態(tài)變量是可以不用我們手動賦值的,它自然會有一個初始值 比如int 類型的初始值就是0 ;boolean類型初始值為false,引用類型的初始值為null 。 這里注意,只是為靜態(tài)變量分配內(nèi)存,此時是沒有對象實(shí)例的
解析:把類中的符號引用轉(zhuǎn)化為直接引用。解釋一下符號引用和直接引用。比如在方法A中使用方法B,A(){B();},這里的B()就是符號引用,初學(xué)java時我們都是知道這是java的引用,以為B指向B方法的內(nèi)存地址,但是這是不完整的,這里的B只是一個符號引用,它對于方法的調(diào)用沒有太多的實(shí)際意義,可以這么認(rèn)為,他就是給程序員看的一個標(biāo)志,讓程序員知道,這個方法可以這么調(diào)用,但是B方法實(shí)際調(diào)用時是通過一個指針指向B方法的內(nèi)存地址,這個指針才是真正負(fù)責(zé)方法調(diào)用,他就是直接引用。
初始化
在初始化階段會調(diào)用類的初始化方法clinit()為靜態(tài)變量賦予實(shí)際的值(例如將value賦值為123)、執(zhí)行靜態(tài)代碼塊。在 JVM 規(guī)范中沒有強(qiáng)制約束加載的時機(jī),不過對于初始化,JVM規(guī)范嚴(yán)格規(guī)定了有且只有5種情況必須立即對類進(jìn)行初始化:
下面我們講解 一下clinit()方法是怎么生成的。clinit()方法是編譯器 自動收集類中的靜態(tài)變量和靜態(tài)語句所產(chǎn)生的。編譯器收集的順序是由語句出現(xiàn)的順序 所 決定的,靜態(tài)語句塊只能復(fù)制定義在它后面的變量,但是不能使用,如下 圖 所示,而且虛擬機(jī)規(guī)范保證,父類的clinit()方法一定 在子類之前執(zhí)行,但不是 通過繼承來的。
以上是jvm類加載的過程可分為哪三步的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!