更改一个变量会改变另一个

时间:2012-07-06 20:22:31

标签: java object

当我创建一个球的实例,然后将其复制到另一个变量时,更改原始也会更改球的副本。例如,采用下面的简化示例:

class Ball() {
    Color _color;
    public Ball(Color startColor) {
        _color = startColor;
    }
    public void setColor(Color newColor) {
        _color = newColor;
    }
}
Ball myBall = new Ball(black);
Ball mySecondBall = myBall;
myBall.setColor(white);

我已经省略了_color的存取方法,但是如果我得到球的颜色,它们现在都是白色的!所以我的问题是:

  • 为什么更改一个对象会更改它的副本,
  • 有没有办法复制对象以便您可以单独更改它们?

5 个答案:

答案 0 :(得分:5)

Ball mySecondBall = myBall;

这不会创建副本。您指定了参考。这两个变量现在引用同一个对象,这就是为什么变量对两个变量都可见的原因 您应该做一些类似于创建new Ball复制相同颜色的内容:

Ball mySecondBall = new Ball(myBall.getColor());

答案 1 :(得分:2)

没有副本,在此作业后有两个对Ball的同一个实例的引用:

Ball mySecondBall = myBall;

要创建副本,请为Ball实现复制构造函数:

class Ball() {
    Color _color;
    public Ball(Color startColor) {
        _color = startColor;
    }
    public Ball(final Ball otherBall) {
        _color = otherBall._color;
    }
    public void setColor(Color newColor) {
        _color = newColor;
    }
}

使用:

Ball myBall = new Ball(black);
Ball mySecondBall = new Ball(myBall);

答案 2 :(得分:0)

您只有一个Ball个对象。 myBallmySecondBall引用都指向同一个Ball对象。

答案 3 :(得分:0)

正如其他人所说,问题是你有两个对同一个实际实例的引用。我喜欢使用的类比是你有两个遥控器用于同一台电视。

如果你想要两个球,你可能会这样做:

class Ball() {
  public Ball(Ball original){
      _color = original.getColor();
  }
...etc...
}

Ball myBall = new Ball(black);
Ball mySecondBall = new Ball(myBall);
myBall.setColor(white);

答案 4 :(得分:0)

上述解决方案肯定会起作用。

对象是复合值,因此通过将对象等同于某个变量不会创建其副本,而是传递其引用。因此,改变一个会影响另一个。 如果有人想知道更多解决方法,可以尝试以下任何一种方法-

  

Ball mySecondBall = JSON.parse(JSON.stringify(myBall));

OR

  

Ball mySecondBall = Object.assign({},myBall);