JVM(17)之 準備 解析 初始化

2021-09-14 01:35:53 字數 1094 閱讀 2688

開發十年,就只剩下這套架構體系了! >>>

在類載入機制的五個階段中,我們已經講完了第乙個階段。剩下的四個階段由於涉及到比較多的類檔案相關的知識,現在講了會看得很吃力,所以我們暫時不會一一的去細講,只說一下大概的用處,讓大家有個概念性的認識。 

裝載之後的階段就是校驗階段了,該階段的目的就是確保上一階段讀進來的二進位制位元組流中包含的資訊符合虛擬機器的規範,並且不會危害虛擬機器自身。校驗主要分為四個方向:檔案格式校驗、元資料校驗、位元組碼校驗和符號引用校驗。 

校驗過後就是準備階段了。該階段就是為類變數分配記憶體以及設定初始值。注意:這裡的分配記憶體和設定初始值針對僅僅只是類變數,如:public static int val = 123;這種被static修飾的變數,但是這個設定初始值並不是將例子中的123設定給val變數,而是將0設定給該變數。因為這裡指的是初始值,也就是預設的值。如boolean型預設的就是false;float型預設的就是0.0f;引用型別就預設為null。 

然後就是解析階段,該階段就是將符號引用替換為直接引用的過程。這兩個名詞我們會在後面講類檔案格式的時候仔細講,大家先記著有這麼乙個階段就好了。 

最後就是初始化的階段了,到了這個階段才會開始執行我們自己寫在類中的**。他執行的是類變數和靜態塊。如下面**: 

還記得剛剛講的準備階段嗎?在準備階段是為類變數設定初始值和分配記憶體(方法區分配),而在該階段則是為該變數賦上我們自己設定的值。到此,小夥伴知道為什麼類方法(靜態方法)不能呼叫普通方法或者普通變數了嗎?因為類變數以及靜態塊各相關方法都在準備階段分配了記憶體,在初始化階段就賦予了值,而此時其他普通的變數並沒有做到這幾步,他們都是在生成例項變數的時候才會進行記憶體的分配(堆中分配),因此如果靜態方法呼叫了乙個普通變數,而此時還沒有建立該普通變數的物件,這就會導致系統錯誤。所以為了避免這種情況,就不允許那樣呼叫了。 

這也是為什麼main方法是靜態方法的原因之一,因為不用建立物件就可呼叫了。建立物件是要消耗記憶體的!! 

在類載入的前面四個階段中,虛擬機器都沒有硬性的規定在什麼情況下才能進行,而初始化階段則有且只有5種情況下才能進行,基於易理解的角度來考慮,我們暫時只說3種:

jvm類初始化條件

1.虛擬機器啟動時,指定乙個要執行的主類,虛擬機會優先初始化這個 帶main方法的 主類 public class testmode public static void main string args 2.通過陣列定義來引用類,不會觸發類的初始化 class test public class ...

初始化 MyBatis初始化之載入初始化

在mybatis初始化過程中,大致會有以下幾個步驟 1.建立configuration全域性配置物件,會往typealiasregistry別名註冊中心新增mybatis需要用到的相關類,並設定預設的語言驅動類為xmllanguagedriver 3.構建defaultsqlsessionfacto...

JVM 五 類的初始化

7種主動使用和被動使用,會觸發類的初始化 當初始化類的時候,要求父類都已經被初始化,但是這條規則不適用於介面 inte ce public class test06 inte ce threadparent class threadchild implements threadparent在這個例子...