首頁  >  文章  >  Java  >  Java從虛擬機器角度分析什麼是類別的實例化順序

Java從虛擬機器角度分析什麼是類別的實例化順序

青灯夜游
青灯夜游轉載
2018-10-20 15:51:142166瀏覽

本篇文章帶給大家的內容是Java從虛擬機器角度分析什麼是類別的實例化順序。有一定的參考價值,有需要的朋友可以參考一下,希望對你們有幫助。

1、先展示實例程式碼(Son.java & Father.java)

public class Father {    
    public static int a=10;//父类的静态变量    static{//父类的静态代码块
        a=20;
    }
    {//父类的构造代码块
        a=30;
    }    
    public Father() {//父类的构造方法
        a=40;
    }
}
public class Son extends Father{    
    public static int s=10;//子类的静态变量    public int k=20;//子类的实例变量    static{//子类的静态代码块
        s=20;
    }
    {//子类的构造代码块
        s=30;
    }    public Son() {//子类的构造函数
        s=40;
    }
    {//子类的构造代码块
        s=50;
    }
}

2、將son.java檔案編譯為son.class文件,然後使用javap反編譯檢視Son的字節碼指令來分析Son的載入順序,更利於理解(javap -v -c Son > p.txt)。

3、執行程式碼"new Son();"後,分析類別的載入順序。

下面的static{};為函數,son();為函數。

static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: bipush        10
         2: putstatic     #11                 // Field s:I--------------------------顺序执行静态变量的赋值
         5: bipush        20
         7: putstatic     #11                 // Field s:I--------------------------顺序执行静态代码块
        10: return
  public packet1020.Son();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0         
         1: invokespecial #16                 // Method packet1020/Father."<init>":()V--------------------执行父类的<init>函数(顺序不变,第一个)
         4: aload_0         
         5: bipush        20
         7: putfield      #18                 // Field k:I------------------------------------------------按顺序收集实例变量赋值
        10: bipush        30
        12: putstatic     #11                 // Field s:I------------------------------------------------按顺序收集构造代码块
        15: bipush        50
        17: putstatic     #11                 // Field s:I------------------------------------------------按顺序收集构造代码块
        20: bipush        40
        22: putstatic     #11                 // Field s:I------------------------------------------------最后执行自己的构造函数代码(顺序不变,最后一个)
        25: return

開始分析:

1.觸發類別的加載,在初始化階段,先執行父類別函數,然後執行子類別函數,按照順序執行靜態變數賦值與靜態程式碼區塊。

2.程式碼中執行了建構函數,所以執行函數。

結論:

1.父類別中順序執行靜態變數賦值,靜態程式碼區塊

2.子類別中順序執行靜態變數賦值,靜態程式碼區塊

3.父類別中順序執行實例變數賦值,建構程式碼區塊

4.父類別建構子

5.子類別中順序執行實例變數賦值,建構程式碼區塊

6.子類別建構子

名字解釋:摘抄自周志明老師的《深入理解Java虛擬機器:JVM高階特性與最佳實務》

1.有且只有4中情況下必須對類別進行初始化(執行函數)中的第三種:初始化一個類別時,先初始化父類別。這就是為什麼父類別的函數先於子類別的函數執行。

2.函數:編譯器依照原始碼中的順序自動收集類別中的所有靜態變數的賦值動作和靜態程式碼區塊中的語句合併而成的。

3.函數:開始先呼叫父類別的函數,然後編譯器會依照原始程式碼中的順序自動收集類別中的實例變數的賦值運算和建構程式碼區塊中的語句合併,然後插入到建構函數方法前面,最後是程式設計師自己寫的建構函數程式碼。

建構程式碼區塊執行順序先於建構子

<init>(){
  1.调用父类<init>方法
  2.顺序执行实例变量的赋值操作和构造代码块
  3.程序员自己的构造函数方法代码
}

總結:以上就是這篇文章的全部內容,希望能對大家的學習有所幫助。更多相關教學請造訪Java影片教學java開發圖文教學bootstrap影片教學

以上是Java從虛擬機器角度分析什麼是類別的實例化順序的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:cnblogs.com。如有侵權,請聯絡admin@php.cn刪除