2017-01-16 52 views
0

我並不認爲new不會在實例變量已分配的情況下更改實例變量。新關鍵字的本地使用

我理解正確嗎?

class Foo { 
    String name = "Java"; 
} 
class Main { 
    public static void main(String args[]) { 
     Foo foos[] = { new Foo(), new Foo() }; 
     foos[0].name = "bar"; 
     for (Foo c : foos) c = new Foo(); 
     for (Foo c : foos) System.out.println(c.name); 
     for (Foo c : foos) c.name = "baz"; 
     for (Foo c : foos) System.out.println(c.name); 
    } 
} 

輸出

bar 
Java 
baz 
baz 

在上面的例子中,new更像鑄造目的是相同的類已經它。這種行爲的實際用途是什麼?

+2

「new」操作符只是在做它的工作,即創建新的對象。我在這裏什麼也看不到,需要解釋。 –

+1

這裏你真的不清楚你的意思......你有3個'new'的用法 - 哪些是你感到驚訝的?這與地區有什麼關係?你期望的結果是什麼?你驚訝於'c = new Foo();'實際上並沒有改變集合中的值嗎?如果是這樣,那麼'new'就沒有任何事情可做。 –

+0

有四個獨立變量'c'。除了第一個循環以外,沒有重新分配。但是這對陣列沒有影響。 – Albjenow

回答

3

這是因爲Java總是通過傳遞值。變量c不反映數組元素,但其參考值被複制。所以起初,c指向數組元素的值,但是當您使用c = new Foo()重新指定c時,變量c將指向其他內容。出於這個原因,數組元素本身不受影響。

  1. 在此代碼,

    for (Foo c : foos) 
    

    參考到陣列元件(例如foos[0])複製到c

  2. 但是,當您將新的Foo實例指定給c時,它不會被陣列反映出來,您只需將其分配給c

    c = new Foo(); 
    
  3. 在一個循環週期,下一個元素重新分配給c,讓你通過c = new Foo()創建鬆散到內存中的對象。這將很快收集垃圾。

我注意到你來自C世界,這解釋了混淆。但在Java中,傳遞給方法的參數或foreach循環中的元素引用始終會被複制。 This post解釋了有關此行爲的更多詳細信息。