I tried out the following code,which has a final
instance variable called data
.This is instantiated in the constructor using an int[]
argument.If an element of the int[] array changes ,the change is reflected in the instance variable and is shown in the show()'s
output.However,if I set the external array to null ,or to a new array,the change is not reflected in the show() output.
why does this happen? if the external array is changed by ext[0]=x ,the change is shown in the inst.variable.It doesnot happen if the ext reference is set to a new object.
public class MutabilityTest {
public static void main(String[] args) {
int[] ext = new int[] {1,2,3,4,5};
FMutable xmut = new FMutable(ext);
mut.show(); //shows [1,2,3,4,5]
System.out.println("changed ext array");
ext[0] = 99;
System.out.println("ext:"+Arrays.toString(ext)); //[99,2,3,4,5]
mut.show(); //shows [99,2,3,4,5]
System.out.println("set ext array to new");
ext = new int[]{8,8,8,8}
System.out.println("ext:"+Arrays.toString(ext)); //[8,8,8,8]
mut.show();//expected [8,8,8,8] but got [99,2,3,4,5]
ext = null;
System.out.println("ext:"+Arrays.toString(ext)); //null
mut.show(); //shows same [99,2,3,4,5]
}
}
class FMutable{
private final int[] data;
public FMutable(int[] indata){
this.data = indata;
}
public void show(){
System.out.println("XMutable:"+Arrays.toString(this.data));
}
}
This has nothing to do with data
being final, or a field elsewhere. You can see the exact same effect much more simply:
int[] x = { 1, 2, 3, 4, 5 };
int[] y = x;
y[0] = 10;
System.out.println(Arrays.toString(x)); // 10, 2, 3, 4, 5
y = new int[] { 3, 3, 3, };
System.out.println(Arrays.toString(x)); // 10, 2, 3, 4, 5
It's important to differentiate between variables, their values, and objects. Think of a variable as being like a piece of paper. It can have a primitive value written on it, or a house address.
The line:
int[] y = x;
or in your sample code:
this.data = indata;
just copies what's written on one piece of paper onto a new piece of paper. That's just the address of the "house" (the array object in this case).
Now those two pieces of paper are themselves independent - changing what's written on one of them doesn't change what's written on the other. However, if you go to the house by following the address on one piece of paper, make a change (e.g. paint the front door) and then go to the house by following the address on the other piece of paper (while they're still the same) then yes, you'll see the freshly painted door. That's what you're seeing when you make a change to the array itself.
See more on this question at Stackoverflow