java 觸發類的初始化的方法

什麼是類的初始化,什麼是類的實例化,什麼狀況下會觸發初始化,可能不少人都有這樣的疑問?java

那麼首先咱們須要瞭解一下jvm的類加載過程。面試

從JVM上來看,類的加載機制從加載到虛擬機內存到卸載出內存,分爲5個階段:裝載,連接(校驗,準備,解析),初始化,使用,卸載。jvm


這裏咱們只分析與咱們相關的幾個過程。函數

1,準備過程spa

例子
code

public class A{
(斷點)  public static int a=1;
  public final static int b=2;
  public int c=3;
}
public class B{
public static void main(String args[]){
 A.a=2;
}
}

賦值靜態域是咱們知道的四種觸發初始化的方法。繼承

那麼咱們在a變量前打斷點。內存

當執行main方法時,代碼第一次運行到斷點的位置時,你會發現get

a=0,b=2.沒有c。這就是類加載機制的準備階段。虛擬機

準備階段:內存分配靜態的類變量和常量.同時會爲靜態變量分配初始值。(分配初始值這個過程不少同窗都會忽略掉)


2.初始化階段

不少筆試或者面試都會問什麼狀況下會觸發初始化。

1,實例化的時候確定是要觸發的new 和Class.forName()

2,類的靜態方法被調用的時候

3,類的靜態域被訪問,被賦值的時候(若是訪問的是靜態常量,則不會觸發初始化)

4,java反射 reflect

大致就是這幾種方式。

初始化 會給靜態變量賦值,執行靜態代碼塊.

若是一個類有static{} 普通{} 構造器函數 A{}都有,還繼承了父類

則執行順序上來看,

例子

class A{
public static int a=1;
static{System.out.println("1")}
      {System.out.println("3")}
public A{System.out.println("4")}
public static getA(){
     System.out.println("7")}
}
class B extends A{
public static int a=1;
static{System.out.println("2)}
      {System.out.println("5")}
public A{System.out.println("6")}
public static getA(){
     System.out.println("8")}
}
public static void main(String args[]){
 //new B;實例化子類 執行順序123456
 //A.a=2 賦值父類靜態變量 ,執行12,a=2
 //A.getA() 執行父類靜態方法 執行127
 //B.getA() 執行子類靜態方法,和重寫沒毛關係,執行128
}
總結:
初始化只會執行靜態代碼塊,實例化會繼續執行普通代碼塊和構造函數。
}
相關文章
相關標籤/搜索