Java数组复制——Arrays.copyOf()地址传递问题

欢迎纠错,转载注明出处,have a nice day!

今天在做项目的时候有个需求要用到二维数组复制,我不假思索地以为和一维数组一样,结果出错了,特此记录一下。

Arrays.copyOf()方法返回的拷贝数组的地址是否指向原数组?

答案很明显是否的,因为在源码中很明显是new了个新数组返回。

public static int[] copyOf(int[] original, int newLength) {
        //new一个新数组,然后调用System.arraycopy复制
        int[] copy = new int[newLength];
        System.arraycopy(original, 0, copy, 0,
                         Math.min(original.length, newLength));
        return copy;
    }

虽然返回的数组地址与原数组不同,但是数组中的数据就未必了,上代码:
新建两个数组,分别存放基本数据和对象,然后对他们进行拷贝,再对拷贝的数组的第一个元素进行修改。可以看出,啊a1数组的元素并未发生改变,而a2数组的元素改变了。

public class TestArraysCopy {
    public static void main(String[] args) {
        int[] a1 = new int[] {1, 2, 3, 4};
        Num[] a2 = new Num[] {new Num(1), new Num(2), new Num(3), new Num(4)};
        
        int[] c1 = Arrays.copyOf(a1, a1.length);
        Num[] c2 = Arrays.copyOf(a2, a2.length);
        
        c1[0] = 0;
        c2[0].num = 0;
        
        System.out.println("a1: " + a1[0] + " c1: " + c1[0]);//a1: 1 c1: 0
        System.out.println("a2: " + a2[0].num + " c2: " + c2[0].num);//a2: 0 c2: 0
    }
}

class Num{
    int num;
    
    public Num(int num) {
        this.num = num;
    }
}

可以看出,对于对象数组的copy,数组中的元素引用的是原数组中对象的地址。我们debug来看一下数组地址


内存地址

发现,a1,a2与c1,c2的数组地址不同,但a2与c2的元素的地址是相同的,所以证实上面的说法。

那么二维数组的拷贝有什么不同吗?

我之前对二维数组的拷贝操作是这样的

        int[][] a3 = new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int[][] c3 = Arrays.copyOf(a3, a3.length);
        
        c3[0][0] = 0;
        
        System.out.println("a3: " + a3[0][0] + " c3: " + c3[0][0]);//a3: 0 c3: 0

我们都知道,数组在java中是看做对象来处理的,如果按照我之前的操作,则会把a3中的每个子数组的地址传递到c3中。所以对二维数组的拷贝要这么做:

int[][] a3 = new int[][] {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        int[][] c3 = new int[a3.length][];
        for (int i = 0; i < a3.length; i++) {
            c3[i] = Arrays.copyOf(a3[i], a3[i].length);
        }
        c3[0][0] = 0;
        
        System.out.println("a3: " + a3[0][0] + " c3: " + c3[0][0]);//a3: 1 c3: 0

先为c3开辟3个新地址,然后就和一维数组拷贝一样了。

注意:当二维数组是对象数组的时候,想要拷贝就只能老老实实用for循环,new一个新对象,将旧对象的数据传递给新对象。

你可能感兴趣的:(Java数组复制——Arrays.copyOf()地址传递问题)