java - 为什么当我使用实例方法返回另一个对象时,我当前的对象被修改了? - java

标签 java object instance

我有这门课,但我不明白到底发生了什么:

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/

相关文章:

java - 为什么 JMH 运行不同的 fork ?

java - Android 上的 onActivityResult 方法内的全局变量值未更改

Python-函数对象创建

javascript - Nodejs :Instance of modules

python - Python 中类型和对象的先有鸡还是先有蛋悖论

java - 创建抽象类或匿名类的实例

java系统找不到指定的文件

apache-flex - 弹性空气 : Read "ActionScript object" from file then cast?

JavaScript 将具有特定结构的对象转换为数组

c++ - 从函数返回错误的实例