How are properties of mutable variables shared among multiple variable references?

StackOverflow https://stackoverflow.com/questions/22250507

  •  11-06-2023
  •  | 
  •  

Question

I'm not sure if this is just me, or if its something I should have known, but if I do :

Object a = 1;
Object b = a;
b = 2;

Then a is the same value as b. Is this normal behaviour? Because I wanted to copy the variable, not reference it.

The reason i ask is i have some code like this :

center = new Point(0.0f,1.0f,1.0f);
returnPoint = center;
...
returnPoint.x = 1.0f;
//For some reason, above modifies center as well as return
Was it helpful?

Solution

You may try something like this:

center = new Point(0.0f,1.0f,1.0f);
returnPoint = center.clone();
...
returnPoint.x = 1.0f;

The clone method will create another instance with the same values.

OTHER TIPS

In "returnPoint = center" you don't copy center, you make a reference to it. Thus when you modify returnPoint, you also modify center.

Then a is the same value as b

No. By doing b = 2, you do b = new Integer(2);. Therefore a and b are not the same anymore.

As to your second example this is normal: returnPoint is the same reference as center; if you modify the contents of returnPoint, you modify those of center since they "refer" to the exact same object. You need to make a copy of center.

One solution other than .clone() is to make a copy constructor (ie, taking another Point as an argument).

Your example

Object a = 1;
Object b = a;
b = 2;

does not describe the same problem as your other code. The above example will result in a = new Integer(1) while b = new Integer(2). Note that integer instances are immutable, something that does not hold for Point.

For understanding what went wrong, consider a mutable integer class:

class MutableInteger {
  public int value;
}

Now let us use this class to recreate the problem in the Point-related code for your first example code:

MutableInteger mi = new MutableInteger();
mi.value = 1;
Object a = mi;
Object b = a;
mi.value = 2;

would result in both a and b pointing to the same instance of MutableInteger. Since you change the latter instance's value, the change of b will effect the value referenced by a. It will however not change the assignment of a!

In order to avoid your problem, you should not share the Point instance. Use:

returnPoint = new Point(center);

in order to create a new point that describes the same coordinates. You can than mutate the copied point without altering the representation of the center point.

In Java, if you have two variables of a data type that is not primitive, setting on equal to the other does not give you a clone. You have to explicitly clone the first variable.

If you want to store the value, you'll need to have 3 float variables and store the value inside they. But remember to use "float", not "Float".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top