前面两篇文章介绍了for循环和clone()方法对数组进行的拷贝,本文来继续总结数值拷贝的另外两种方式。
先来看看基本数据类型的System.arraycopy() 方法拷贝:
import java.util.Arrays;
public class TestDemo {
public static void main(String[] args) {
int[] array1 = new int[]{1,2,8,7,6};
int[] array2 = new int[array1.length];
System.arraycopy(array1, 0, array2, 0, array1.length);
System.out.println("array1 = " + Arrays.toString(array1));
System.out.println("array2 = " + Arrays.toString(array2));
System.out.println("=========================");
array2[0] = 100;
System.out.println("array1 = " + Arrays.toString(array1));
System.out.println("array2 = " + Arrays.toString(array2));
}
}
这段程序的结果是:
array1 = [1, 2, 8, 7, 6]
array2 = [1, 2, 8, 7, 6]
=========================
array1 = [1, 2, 8, 7, 6]
array2 = [100, 2, 8, 7, 6]
由结果可以看出,当对复制数组的某个元素进行改变时,并不影响被复制数组对应元素,即对于基本数据类型来说System.arraycopy() 方法是深拷贝。
看一下内存分析:
同样的,看一下当对象不是基本数据类型,而是引用数据类型时的情况。看以下例子:
class TestArray{
private int val = 10;
public void setVal(int val){
this.val = val;
}
public int getVal(){
return this.val;
}
}
public class TestDemo {
/**数组输出方法 */
public static void printArray(TestArray[] array){
for(int i = 0;i < array.length;i++){
System.out.print(array[i].getVal()+" ");
}
System.out.println();
}
public static void main(String[] args) {
TestArray[] array1 = new TestArray[3];
// 数组引用赋值
for (int i = 0; i < array1.length; i++){
array1[i] = new TestArray();
}
TestArray[] array2 = new TestArray[array1.length];
// 数组System.arraycopy()方法复制
System.arraycopy(array1,0,array2,0,array1.length);
printArray(array1);
printArray(array2);
System.out.println("==========");
array2[0].setVal(100);;
printArray(array1);
printArray(array2);
}
}
这段程序的结果是:
10 10 10
10 10 10
==========
100 10 10
100 10 10
由结果可以看出,当对复制数组的某个元素进行改变时,被复制数组对应元素也随之改变,即对于引用数据类型来说 System.arraycopy() 方法是浅拷贝。
看一下内存分析:
通过内存分析可以很直观的看到,每个数组的元素分别指向同一个内存地址,当通过其中一个数组的某个元素对被指向地址的数值进行更改时,另一个数组相应的元素同样会发生改变。
先来看看Arrays.copyOf()方法的源码:
public static int[] copyOf(int[] original, int newLength) {
int[] copy = new int[newLength];
System.arraycopy(original, 0, copy, 0,
Math.min(original.length, newLength));
return copy;
}
可以看到其实Arrays.copyOf()方法在底层是调用了 System.arraycopy() 方法来实现复制,即可以把Arrays.copyOf() 方法看作是 System.arraycopy() 方法的衍生方法,故它的执行机理与 System.arraycopy() 方法相同。
所以 Arrays.copyOf() 方法对于基本数据类型来说是深拷贝,对引用类型来说是浅拷贝。