jvm類別載入的過程分為三個步驟:載入、連接和初始化。
載入
透過類別的全路徑將這個類別從外部載入到jvm中,同時在方法區產生該類別的描述資訊並在記憶體產生該類別的Claas類型。作為方法區這個類別的資料存取入口。
連接
這是很重要的一步,流程比較複雜,分成三個步驟:驗證、準備和解析。
驗證:確保類別載入的正確性。一般情況由javac編譯的class檔是不會有問題的,但是可能有人的class檔是自己用其他方式編譯出來的,這就很有可能不符合jvm的編譯規則,這一步就是要過濾掉這部分不合法檔案
準備:為類別的靜態變數分配內存,將其初始化為預設值 。我們都知道靜態變數是可以不用我們手動賦值的,它自然會有一個初始值 例如int 類型的初始值就是0 ;boolean型別初始值為false,引用型別的初始值為null 。這裡注意,只是為靜態變數分配內存,此時是沒有物件實例的
解析:把類別中的符號引用轉換為直接引用。解釋一下符號引用和直接引用。例如在方法A中使用方法B,A(){B();},這裡的B()就是符號引用,初學java時我們都知道這是java的引用,以為B指向B方法的記憶體位址,但這是不完整的,這裡的B只是一個符號引用,它對於方法的呼叫沒有太多的實際意義,可以這麼認為,他就是給程式設計師看的一個標誌,讓程式設計師知道,這個方法可以這麼調用,但是B方法實際調用時是透過一個指針指向B方法的記憶體位址,這個指針才是真正負責方法調用,他就是直接引用。
初始化
在初始化階段會呼叫類別的初始化方法clinit()為靜態變數賦予實際的值(例如將value賦值為123)、執行靜態程式碼塊。在JVM 規範中沒有強制約束載入的時機,不過對於初始化,JVM規範嚴格規定了有且只有5種情況必須立即對類別進行初始化:
下面我們講解一下clinit()方法是怎麼生成的。 clinit()方法是編譯器 自動收集類別中的靜態變數和靜態語句所產生的。編譯器收集的順序是由語句出現的順序所決定的,靜態語句塊只能複製定義在它後面的變量,但是不能使用,如下圖所示,而且虛擬機規範保證,父類的clinit()方法一定在子類別之前執行,但不是透過繼承來的。
以上是jvm類別載入的過程是什麼?的詳細內容。更多資訊請關注PHP中文網其他相關文章!