2017-04-01 19 views
7

我瞭解到,初始化順序分配原則是訂單:在Java中,什麼是初始化爲後主要方法這些語句

  1. 超類第一個(在此情況下,這裏討論)
  2. 靜態變量聲明和靜態初始化塊在外觀
  3. 的順序
  4. 實例變量聲明和靜態初始化塊中出現的順序
  5. 構造

但我還在這個代碼的輸出困惑:

public class Test1 { 

    static { 
     add(2); 
    } 

    static void add (int num) { 
     System.out.println(num + " "); 
    } 

    public Test1() { 
     add(5); 
     System.out.println("Constructor!"); 
    } 

    static { 
     add(4); 
    } 

    { 
     add(6); 
    } 

    static { 
     new Test1(); 
    } 

    { 
     add(8); 
    } 

    public static void main(String[] args) { 
     System.out.println("Main method!"); 
     add(10); 
    } 

    { 
     add(11); 
    } 
    static { 
     add(12); 
    } 
} 

結果是:

2 
4 
6 
8 
11 
5 
Constructor! 
12 
Main method! 
10 

如果沒有附加的(10)的發言;加(11);加(12);我完全可以理解。你能解釋一下這3條語句的初始化順序嗎?

+1

要調用*類的初始化,迫使非靜態初始化塊來執行的過程中構造函數代碼*,但沒有按」這意味着它會打破靜態初始化順序。所以你看到'靜態2 4';非靜態(但被稱爲* from * static block)'6 8 11',構造函數'5';然後再靜止塊'12'的其餘部分。現在當類完全初始化時,JVM執行'main'方法('10')。 – Pshemo

+0

您忽略了常量的初始化,這很快就會發生。爲什麼不閱讀關於初始化序列的JLS章節? –

回答

6

1)塊被稱爲「實例初始化」時新對象將被創建它像缺省構造函數或noArg構造函數只被調用。

{ 
    add(11); 
} 

2)在上面的代碼中你有靜態塊哪個會首先拜訪了類加載自身),實例初始化在創建對象)其中被調用,明確DefaultConstructor創建對象時調用,但始終記得實例初始值設定優先)和最後一個Main方法。

3)現在讓我們來分析你的代碼,

第一個呼叫:

static 
{ 
    add(2); //print 2 
} 

第二個呼叫:

static { 
     add(4); // print 4 
} 

第三個呼叫:

static { 
    new Test1(); 
    // Here Object is getting created so all Instance Initialzer will be called first in a sequential manner. 
} 

第四電話:

{ 
    add(6); // print 6 
} 

5呼叫:

{ 
    add(8); // print 8 
} 

第六輪:

{ 
    add(11); // print 11 
} 

第7次調用:實例初始化程序之後,將調用顯式默認構造函數。

public Test1() { 
    add(5); // print 5 
    System.out.println("Constructor!"); // print Constructor! 
} 

8日來電:再次最後的靜態塊將被調用。

static { 
    add(12); // print 12 
} 

9號電話:最後的主要方法將被調用

public static void main(String[] args) { 
    System.out.println("Main method!"); // print Main method! 
    add(10); // print 10 
} 
6

靜態初始化是第一次,所以你得到

2 
4 

但在接下來的靜態初始化你叫Test1.class的新實例,所以實例初始化被觸發,之後他們觸發構造函數,你會得到:

6 
8 
11 
5 
Constructor! 

之後,其餘的靜態初始化程序被調用。所以:

12 

以及最後是主要方法:

Main method! 
10 
1

我想你困惑,因爲(12)之前(主要方法 - 10)

這是因爲所謂的主要方法最後但其他初始化順序清除

1

在Java中,對於一個類全部靜態初始化程序按順序執行(從上到下依次爲類)之前全部構造函數。 {}中的術語添加到構造函數中,這些不是靜態初始化函數(請參閱http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html)。

所以實例1的Test1的:

static { 
    add(2); 
} 
... 
static { 
    add(4); 
} 

然後,有一個靜態塊中的Test1的構造。這就是所謂的,所以實例成員被初始化,因爲之前的靜態初始化一直呼籲:

{ 
    add(6); 
} 
... 
{ 
    add(8); 
} 
... 
{ 
    add(11); 
} 

後,在構造函數中的下一個操作被稱爲:

add(5); 

然後,我們在第一時間返回有最後的靜態initiazer被稱爲:

static { 
    add(12); 
} 

最後,類,如果完全初始化,所以主要的方法被稱爲:

public static void main(String[] args) { 
    System.out.println("Main method!"); 
    add(10); 
} 

所以,輸出:

2 
4 
6 
8 
11 
5 
Constructor! 
12 
Main method! 
10 
1

無論@DontPanic已回答是正確的,我想強調的要點是,在代碼塊的的順序(從上到下)源代碼也很重要,你可以從Java文檔看here

一個類可以有任意數量的靜態初始化塊,它們可以出現在類體中的任何地方。運行時系統保證 靜態初始化塊的調用順序是它們在源代碼中出現的次數爲 。不具有名稱,如下面

相關問題