2013-07-11 55 views
0

我認爲java不會用四個值初始化a。但是我錯了,你能解釋我是怎麼做到的嗎?我的意思是它在調用構造函數時的作用,因爲我沒有在構造函數中初始化a當對構造函數進行調用時會發生什麼(在這種情況下清晰的概念)?

class A { 
    int[] a = {1,2,3,4}; 
    A() { 
     a[0] = 3; 
    } 
} 

class ClassTest1 { 
    public static void main(String args[]) { 
     A b = new A(); 

     System.out.println("hey " + b.a[0]); 
     System.out.println("hey " + b.a[1]); 
    } 
} 

如果你詳細解釋一些外部資源並理解內部信息,對新手來說可能會更好。

+0

http://stackoverflow.com/a/9665533/995891是一個有趣和相似的情況。這是關於Java – zapl

+0

http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.5 – nachokk

+0

@zapl的初始化順序感謝,有趣的討論..與「所有變量被初始化爲它們的默認值,然後顯式初始化程序和匿名塊按它們在源文件中找到的順序運行,最後調用構造函數。 http://stackoverflow.com/a/9665723/1579939 – netsmertia

回答

4

當您有int[] a = {1,2,3,4}時,它會將該行編譯到構造函數的頂部。所以你的構造函數看起來像這樣:

a = {1,2,3,4}; 
a[0] = 3; 

現在,這是一個非常簡單的定義。如果你有多個構造函數,你可以把它看作所有的構造函數,但是你也可以把它看作只放入其中的一個(你實際調用的那個......)。

考慮一下:

class Counter { 
    static int nextId = 0; 
    static int nextId() { return nextId++; } 

    final int id = nextId(); 
    final String name; 

    public Counter() { 
     this("Unnamed counter"); 
    } 
    public Counter(String name) { 
     this.name = name; 
    } 

} 

所以,你必須創建一個沒有名稱的計數器的選項,你得到的只是一個默認名稱。現在從上面的例子,你可以推斷出你的構造神奇地變成如下:

public Counter() { 
    this.id = nextId(); 
    this("Unnamed counter");   
} 
public Counter(String name) { 
    this.id = nextId(); 
    this.name = name; 
} 

但我們知道這是不行的 - 它試圖設置id在通用構造,但是隨後陷入命名構造函數並嘗試再次設置它。一旦設置完畢,你就不能設置最終變量!

所以,我們可以這樣想:我們實際調用的任何構造函數都會獲得額外的初始化行,但可能會鏈接的構造函數不會獲得額外的行。

+0

所以每個被重寫的構造函數都會有'a = {1,2,3,4}'。 – netsmertia

+0

是的,他們會的。但它只應該被調用一次。所以,如果你鏈構造函數,說'公共A(){this(null); a [0] = 3; } public A(Object o){System.out.println(「lol」); }'它應該只分配一次(這很重要,如果你有類似'int id = IdFactory.next();'! – corsiKa

+0

你是說如果我初始化兩個對象'A x = new A()'和'A y = new A(ObjRf)''''a'僅針對第一個對象進行初始化 – netsmertia

相關問題