java程序執行順序理解


 

public class StaticTest
{
    public static int k = 0;
    public static StaticTest t1 = new StaticTest("t1");
    public static StaticTest t2 = new StaticTest("t2");
    public static int i = print("i");
    public static int n = 99;
    public int j = print("j");
    {
        print("構造塊");
    }
    static
    {
        print("靜態塊");
    }
    public StaticTest(String str)
    {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++n;
        ++i;
    }
    public static int print(String str)
    {
        System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
        ++i;
        return ++n;
    }
    public static void main(String[] args)
    {
        StaticTest t = new StaticTest("init");
    }
}

1. 首先加載類,加載類過程中對於定義的靜態字段分配內存空間,也是在方法區中,並進行零初始化,即數字類型初始化為0,boolean初始化為false,引用類型初始化為null等。這也就是為什么剛開始i=0,n=0

2. 執行第一句public static int k = 0;對k進行賦值

3. 執行第二句public static StaticTest t1 = new StaticTest("t1");這是定義了一個類的靜態對象,在t1對象初始化時先執行非靜態方法或者非靜態常量,順序執行,接着運行構造參數。意思是當聲明了對象名后,我的類有了一個對象,就默認調用了類中定義的非靜態的變量     和方法,依次進行;所以這時就會調用public int j = print("j");

   此時會調用print方法,其中++i,i=1=i+1; 返回值++n,n=1=n+1;j=1,k=1.

   打印  1:j i=0 n=0

   然后執行非靜態塊print("構造塊");調用print函數

   打印  2:構造塊 i=1 n=1

   沒有了非靜態的方法,塊或常量后,之后會對t1初始化,執行類的構造函數public StaticTest(String str);

   打印  3:t1 i=2 n=2

4. 執行第三句public static StaticTest t2 = new StaticTest("t2");和上面一步的分析方法一樣。

   依次打印

          4:j i=3 n=3

          5:構造塊 i=4 n=4

          6:t2 i=5 n=5

5. 執行第四句public static int i = print("i");調用print方法

    打印  7:i i=6 n=6

6. 執行第五句public static int n = 99;至此靜態變量加載完畢,然后加載靜態塊和靜態方法的聲明,只有當調用靜態方法時才執行靜態方法的內容。

7. 執行第六句static{ print("靜態塊"); } 所以調用print函數

    打印  8:靜態塊 i=7 n=99 由於n在上一步初始化了。

8. 執行main函數體StaticTest t = new StaticTest("init");同樣分析思路和第3步是一樣的,當聲明了對象t時,程序會先執行非靜態塊和變量以及非靜態方法的聲明。然后執行類對象的初始化。所以先執行public int j = print("j");調用了print函數

    打印  9:j i=8 n=100

    然后執行非靜態塊print("構造塊");調用了print函數

    打印  10:構造塊 i=9 n=101

   最后執行對象的初始化,調用了構造函數public StaticTest(String str);

   打印  11:init i=10 n=102 

程序的入口函數依然是main函數,這里的知識點在於程序時類的加載過程和java虛擬機的內存分配。程序執行的順序是,java虛擬機加載由.java編譯生成出的.class字節碼文件,將其加載至內存,然后找到了main函數,但並不是運行main函數的第一句,而是加載類的數據,當加載一個類時,JVM會根據屬性的數據類型第一時間賦默認值(一舉生成的),即數字類型初始化為0boolean初始化為false,引用類型初始化為null。然后再進行靜態屬性初始化,並為靜態屬性分配內存空間,靜態方法的聲明,靜態塊的加載,沒有優先級之分,按出現順序執行,靜態部分僅僅加載一次。至此為止,必要的類都已經加載完畢,對象就可以被創建了。

當對象被創建時,就會調用類的動態屬性,普通方法聲明,構造塊。最后在調用構造函數。

總的來說調用過程如下:

先加載類的靜態屬性(變量),靜態塊,靜態方法的聲明

然后當定義了類的對象時,調用非靜態屬性(變量),構造塊,普通方法聲明。最后對象初始化調用類的構造函數。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM