2017-01-16 55 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解释了有关此行为的更多详细信息。