我有这门课,但我不明白到底发生了什么:
public class Table {
private int[][] array;
private int N;
// constructor
public Table(int[][] array) {
N = array.length;
this.array = Arrays.copyOf(array, N);
}
// this method returns another Table object
public Table tweak() {
int[][] tweak = Arrays.copyOf(array, N);
// here I change the array
return new Table(tweak);
}
}
问题是当我调用调整方法时,用于调用该方法的对象也会发生变化:
public class TestCls {
public static void main(String[] args) {
int[][] array = {{1, 2},
{3, 4}};
Table a = new Table(array);
System.out.println(a.toString());
/* this will print
* 1 2
* 3 4
*/
Table b = a.tweak();
System.out.println(b.toString());
/* this will print
* 2 1
* 3 4
*/
System.out.println(a.toString());
/* this will also print
* 2 1
* 3 4
*/
}
}
请帮助我理解为什么会发生这种情况,以及我应该如何更改调整方法以使原始对象不发生更改。
谢谢
最佳答案
Arrays.copyOf
正在创建一个新的 int[][]
,但这需要一个浅副本 - 它相当于:
int[][] tweak = new int[array.length][];
for (int i = 0; i < tweak.length; i++) {
tweak[i] = array[i];
}
因此,虽然您有一个新的“顶级”数组,但每个“子数组”都是共享的。您确实想要制作数组的深层副本:
int[][] tweak = new int[array.length][];
for (int i = 0; i < tweak.length; i++) {
tweak[i] = array[i].clone(); // Simpler way of performing a shallow copy
}
这对每个“子数组”执行浅拷贝,但这很好,因为元素类型只是 int
(无法使其“更深”)。
请注意,您只需在构造函数中的 tweak
方法或中进行此操作。复印两份是没有意义的。
关于java - 为什么当我使用实例方法返回另一个对象时,我当前的对象被修改了? - java ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15640527/