1. 程式人生 > >java程式執行順序理解

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。然後再進行靜態屬性初始化,併為靜態屬性分配記憶體空間,靜態方法的宣告,靜態塊的載入,沒有優先順序之分,按出現順序執行,靜態部分僅僅載入一次。至此為止,必要的類都已經載入完畢,物件就可以被建立了。

當物件被建立時,就會呼叫類的動態屬性,普通方法宣告,構造塊。最後在呼叫建構函式。

中的來說呼叫過程如下:

先載入類的靜態屬性(變數),靜態塊,靜態方法的宣告

然後當定義了類的物件時,呼叫非靜態屬性(變數),構造塊,普通方法宣告。