数组复制

在谈数组复制之前,先回忆一下浅拷贝和深拷贝:

  • 浅拷贝是指将引用复制给一个变量,即只是增加一个指针指向目标内存地址
  • 深拷贝是指用新开辟的内存空间拷贝目标对象后,让变量指向这个新的内存地址

所以,浅拷贝后,如果新旧任一变量对应的对象发生变动时,另一变量也将变动,而深拷贝不会,因为指向的是不同的对象。

首先无论是对于基本类型数组还是对象类型数组,一般是不能够使用=直接复制的,因为这样只是将引用复制给变量,指向的还是同一个数组。

Java中对于基本类型的数组复制时,复制时因为没有对象的概念,所以不必考虑深拷贝还是浅拷贝,复制后都是两个变量指向不同的数组对象。 当然是实际上都是深拷贝

而对于对象类型的数组时,则都是浅拷贝,因为设计时,深拷贝的使用场景相对较少而且性能很差,如果的确需要深拷贝时,单独实现即可。

特别的,对于String类,由于其不可变性,String类型的数组的拷贝可以理解为都是深拷贝

Java数组的复制有如下四种方式:

1. Object.clone()

此方法是数组对象从Object类继承过来的。

1
2
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1.clone();

2. System.arraycopy()

此方法内部调用的是一个native方法
public static native void arraycopy(Object src, int srcPos,Object dest, int destPos, int length);
内部参数分别为 源数组、 拷贝开始位置、 目标数组、 粘贴开始位置、 拷贝个数

1
2
3
int[] arr3 = {1, 2, 3};
int[] arr4 = new int[3];
System.arraycopy(arr3, 0, arr4, 0, arr3.length);

3. Arrays.copyOf()

此方法内部也是调用了System.arraycopy()方法
public static int[] copyOf(int[] original, int newLength) {}, 第一个参数为源数组,第二个参数为拷贝长度。

1
2
int[] arr5 = {1, 2, 3};
int[] arr6 = Arrays.copyOf(arr5, arr5.length);

4. Arrays.copyOfRange()

内部同样也是调用了System.arraycopy()方法
public static int[] copyOfRange(int[] original, int from, int to){},第一个参数为源数组,第二个参数为拷贝起始位置,第三个参数为拷贝结束位置(不包含)。

1
2
int[] arr7 = {1, 2, 3};
int[] arr8 = Arrays.copyOfRange(arr7, 0, arr7.length); //左闭右开