在写Java时会遇到一种情况:如下
int[] primes = {1, 4, 2, 5};
int[] nums = primes;
我们在修改nums时primes也会跟着改变,这就涉及到深浅拷贝的问题。
Java中存在两种拷贝(这里以数组拷贝为例):深拷贝和浅拷贝,理解java的内存开辟原理就非常容易理解深浅拷贝的区别,深拷贝就是另开辟一块存储空间,浅拷贝共享存储。
深拷贝:拷贝后数组不存在关联,修改一方都不会引起另一方的改变
浅拷贝:修改一方后另一方也随之改变
那么来看一下深浅拷贝都是怎么使用的,本文主要讲解四种方式:
一、for循环非常容易理解,就是首先实例化一个与原数组大小相同的数组,然后通过循环将原数组赋值给拷贝数组(深拷贝)。
注意:当数组元素是引用类型时是浅拷贝
Arrays.copyOf(原数组,自定义新数组长度);
Arrays.copyOfRange(原数组,from,to);
注意拷贝截取的范围是左闭右开的[from,to)
public static void main(String[] args) {
int[] A = {1,2,3,4,5};
int[] B = Arrays.copyOf(A,A.length);
int[] C = Arrays.copyOfRange(A,1,3);
System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]
System.out.println("C : " + Arrays.toString(C)); //C : [2, 3]
System.out.println("===========修改后===========");
A[0] = 100;
System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]
System.out.println("C : " + Arrays.toString(C)); //C : [2, 3]
}
当元素是引用类型时为浅拷贝。
三、arraycopy当数组中存放的元素为基本数据类型时,此时发生的是深拷贝;
System.arraycopy(src, srcPos dest, destPos, length);
其中各个参数分别表示 如下:
src :源数组
srcPos:源数组要复制的起始位置
dest:目标数组
destPos:目标数组复制的起始位置
length:复制的长度
public static void main(String[] args) {
int[] A = {1,2,3,4,5};
int[] B = new int[A.length];
//System.arraycopy(A,0,B,0,A.length);
System.arraycopy(A,1,B,2,2);
System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [0, 0, 2, 3, 0]
System.out.println("===========修改后===========");
A[0] = 100;
System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [0, 0, 2, 3, 0]
}
当元素是引用类型时为浅拷贝。
四、clone同样当数据元素为基本类型时为深拷贝,当是引用类型时为浅拷贝
public static void main(String[] args) {
int[] A = {1,2,3,4,5};
int[] B = A.clone();
System.out.println("A : " + Arrays.toString(A)); //A : [1, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]
System.out.println("===========修改后===========");
A[0] = 100;
System.out.println("A : " + Arrays.toString(A)); //A : [100, 2, 3, 4, 5]
System.out.println("B : " + Arrays.toString(B)); //B : [1, 2, 3, 4, 5]
}
五、总结
| 拷贝方式 | 数值类型 | 引用类型 | 推荐使用 |
|---|---|---|---|
| for循环 | 深拷贝 | 浅拷贝 | |
| copyOf | 深拷贝 | 浅拷贝 | √ |
| arraycopy | 深拷贝 | 浅拷贝 | √ |
| clone | 深拷贝 | 浅拷贝 |



