9
public class DrumKitTestDrive {
/**
 * @param args
 */
public static void main(String[] args) {
    // TODO Auto-generated method stub
    Echo e1 = new Echo();
    Echo e2 = new Echo();
//      **e2 = e1;**

    int x=0;
    while( x < 4 ){
        e1.hello();
        e1.count = e1.count + 1;
        if(x==3){
            e2.count = e2.count + 1;
        }
        if(x>0){
            e2.count = e2.count + e1.count;
        }
        x = x + 1;
    }
    System.out.print(e2.count);
    }
}

class Echo {
    int  count = 0;

    void hello(){
        System.out.println("Hellooooo....");
    }
}

此代码的输出将是:

Hellooooo....
Hellooooo....
Hellooooo....
Hellooooo....
10

但是,如果我在运行代码时删除注释,// e2= e1;系统将打印24而不是10。我不明白为什么会这样?

我的理解是系统只会将实例的值复制e1e2实例中。如果系统会这样做,结果将保持不变,因为两个对象属于同一类。

4

4 回答 4

22

我的理解是系统只会将 e1 实例的值复制到 e2 实例中。

不,当你e2 = e1复制对象引用时——你不是在复制对象——所以变量e1e2都指向同一个对象

因此,当您进行增量时,它们都在增加相同的计数字段。

只有在没有分配的情况下e2 = e1,增量才会发生在两个不同的实例上。

于 2012-08-18T16:51:35.353 回答
7

这是Java的基本原则之一。每个变量,只是某个对象的句柄。执行

e1=e2

不复制对象的值,它指向handles创建的第二个对象。您实例化的第一个Echo对象现在根本没有被引用,并且将在下次 gc 运行时被垃圾收集。

于 2012-08-18T16:54:02.053 回答
5

将一个对象分配给另一个对象只是分配对象引用(或多或少的指针)。它不会复制成员变量等。

您需要阅读有关克隆的信息。从 wiki for Java 的第一段clone()

在 Java 中,对象是通过引用变量来操作的,并且没有用于复制对象的操作符——赋值操作符复制的是引用,而不是对象。clone() 方法提供了这个缺失的功能。

于 2012-08-18T16:53:34.447 回答
0

尝试为方法 Echo 创建构造函数,并将另一个对象作为参数。并将参数对象的值分配给该对象。IE '''

Echo(Echo echo) {
  this.count = echo.count;
}

'''

然后将节点 e2 创建为:

Echo e2 = new Echo(e1);
于 2020-04-21T15:26:15.577 回答