final
というインスタンス変数を持つ次のコードを試してみましたdata
。これは、引数を使用してコンストラクターでインスタンス化されますint[]
。int[] 配列の要素が変更された場合、変更はインスタンス変数に反映され、show()'s
出力に表示されます。ただし、外部配列を null または新しい配列に設定すると、変更は show() 出力に反映されません。
なぜこれが起こるのですか?外部配列が ext[0]=x によって変更された場合、変更は inst.variable に表示されます。ext 参照が新しいオブジェクトに設定されている場合は発生しません。
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));
}
}