Changing one variable changes another

2020-03-26 07:29发布

When I create an instance of a ball, and then make a copy of it to another variable, changing the original changes the copy of the ball as well. For example, take the very simplified example below:

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);

I've elided an accessor method for _color, but if I get the color of the balls, both of them are now white! So my questions are:

  • Why does changing one object change a copy of it, and
  • Is there a way to copy an object so that you can change them independently?

标签: java object
5条回答
劫难
2楼-- · 2020-03-26 07:45

There is no copy, there are two references to the same instance of Ball after this assignment:

Ball mySecondBall = myBall;

To create a copy, implement a copy constructor for 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;
    }
}

To use:

Ball myBall = new Ball(black);
Ball mySecondBall = new Ball(myBall);
查看更多
▲ chillily
3楼-- · 2020-03-26 07:47

You have only one Ball object. Both myBall and mySecondBall references pointing to same Ball object.

查看更多
等我变得足够好
4楼-- · 2020-03-26 07:51

As others have said, the issue is that you have two references to the same actual instance. An analogy I like to use is that you have two remote controls for the same television.

If you want to have two balls, you might do something like:

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

Ball myBall = new Ball(black);
Ball mySecondBall = new Ball(myBall);
myBall.setColor(white);
查看更多
唯我独甜
5楼-- · 2020-03-26 07:59

The above solution will surely work.

Objects are compound values, hence by equating an object to some variable doesn't create its copy, rather passes its reference. Therefore changing one will affect another. If someone wanna know more ways to solve this, they can try any of the below methods-

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

OR

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

查看更多
姐就是有狂的资本
6楼-- · 2020-03-26 08:12

Ball mySecondBall = myBall;

This does not create a copy. You assign a reference. Both variable now refer to the same object that is why changes are visible to both variables.
You should be doing something like to create a new Ball copying the same color:

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

查看更多
登录 后发表回答