JVM中java類的載入時機

來源:互聯網
上載者:User

標籤:java類的載入時機   java類的初始化   被動引用和主動引用   jvm類載入   class初始化   

Java虛擬機器把描述類的資料從Class檔案載入到記憶體,並對資料進行校正、轉換解析和初始化,最終形成可以被虛擬機器直接使用的Java類型,這就是虛擬機器的載入機制。
類從被載入到虛擬機器記憶體中開始,到卸載出記憶體為止,它的整個生命週期包括了:載入(Loading)、驗證(Verification)、準備(Preparation)、解析(Resolution)、初始化(Initialization)、使用(using)、和卸載(Unloading)七個階段。其中驗證、準備和解析三個部分統稱為串連(Linking),如下如所示。


這七個階段,載入、驗證、準備、初始化和卸載這五個階段的順序是確定的,類的載入過程必須按照這個順序來按部就班地開始,而解析階段則不一定,它在某些情況下可以在初始化階段後再開始。

類的生命週期的每一個階段通常都是互相交叉混合式進行的,通常會在一個階段執行的過程中調用或啟用另外一個階段。
Java虛擬機器規範沒有強制性約束在什麼時候開始類載入過程,但是對於初始化階段,虛擬機器規範則嚴格規定了有且只有四種情況必需立即對類進行“初始化”(而載入、驗證、準備階段則必需在此之前開始),這四種情況歸類如下:

1.遇到new、getstatic、putstatic或invokestatic這4條位元組碼指令時,如果類沒有進行過初始化,則需要先觸發其初始化。產生這4條指令最常見的Java代碼情境是:使用new關鍵字執行個體化對象時、讀取或者設定一個類的靜態欄位(被final修飾、已在編譯器把結果放入常量池的靜態欄位除外)時、以及調用一個類的靜態方法的時候。
2.使用java.lang.reflect包的方法對類進行反射調用的時候,如果類沒有進行過初始化,則需要先觸發其初始化。
3.當初始化一個類的時候,如果發現其父類還沒有進行過初始化,則需要觸發父類的初始化。
4.當虛擬機器啟動時,使用者需要指定一個執行的主類(包含main()方法的類),虛擬機器會先初始化這個類。
對於這四種觸發類進行初始化的情境,在java虛擬機器規範中限定了“有且只有”這四種情境會觸發。這四種情境的行為稱為對類的主動引用,除此以外的所有引用類的方式都不會觸發類的初始化,稱為被動引用。

下面通過三個執行個體來說明被動引用:

樣本1:

父類SuperClass.java public class SuperClass {      static{           System.out.println("SuperClass init!");        }       public static int value = 123;  }  子類SubClass.java     public class SubClass extends SuperClass {       static{          System.out.println("SubClass init!");      }  }   主類NotInitialization.javapublic class NotInitialization {      public static void main(String[] args) {          System.out.println(SubClass.value);      }  }  
輸出結果:SuperClass init! 123  


由結果可以看出只輸出了“SuperClass init!”,沒有輸出“SubClass init!”。這是因為對於靜態欄位,只有直接定義該欄位的類才會被初始化,因此當我們通過子類來引用父類中定義的靜態欄位時,只會觸發父類的初始化,而不會觸發子類的初始化。

樣本2:

SuperClass[ ]   scs=new SuperClass[11];


如上,當初始化一個對象數組的時候,也不會觸發類的初始化。

樣本3:

public class ConstClass {   static {    system.out.printl("const");}   public static final int age =123;  }public class NotInitialization{     public static void main(String[ ] args){     system.out.println(ConstClass.age);}

此時並不會出現 “const”,因為在NotInitialization類在編譯的時候已經把ConstClass中的變數age放在常量池中了,訪問時直接取出age即可,不會引發ConstClass的初始化。

 

 

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

JVM中java類的載入時機

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.