作者:@TheMythWS.
专栏:《JavaSE》
座右铭:不走心的努力都是在敷衍自己,让自己所做的选择,熠熠发光。
目录
什么是数组的拷贝?
数组的深拷贝和浅拷贝:
深拷贝:
浅拷贝:
深拷贝和浅拷贝跟是不是for循环拷贝有关系吗?
拷贝,是由英文copy的音译词,copy意为复制,数组的拷贝,简单的理解就是对原有的数组进行一次备份,创建了一个新的数组对象,这个新的数组对象里面的值跟原有数组对象里面的值相同。
首先先问大家一个问题,以下代码实现了拷贝吗?
import java.util.Arrays;
public class OnlineTest {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array1 = {1, 2, 3, 4};
System.out.println(Arrays.toString(array1));
int[] array2 = array1;
System.out.println(Arrays.toString(array2));
System.out.println(array1);
System.out.println(array2);
}
}
运行结果:
从结果,可以看出好像是进行了一次数组的拷贝,其实这个不是真正的拷贝,我们可以看下两个数组的地址,发现它们是同一块地址,说明此时只有一个数组对象,所以不叫拷贝。
接下来我们实现拷贝,最基本的是用for循环拷贝,这里就不介绍了,下面介绍clone()方法来拷贝数组。
import java.util.Arrays;
public class OnlineTest {
//这是一个main方法,是程序的入口:
public static void main(String[] args) {
int[] array1 = {1, 2, 3, 4};
int[] array2 = array1.clone();
System.out.println(Arrays.toString(array1));
System.out.println(Arrays.toString(array2));
System.out.println(array1);
System.out.println(array2);
}
}
运行结果:
从结果可以看出,已经创建了一个新的数组对象。
array2[0] = 11,会不会影响array1[0]的值?
import java.util.Arrays; public class OnlineTest { //这是一个main方法,是程序的入口: public static void main(String[] args) { int[] array1 = {1, 2, 3, 4}; int[] array2 = array1.clone(); array2[0] = 11; System.out.println(Arrays.toString(array1)); System.out.println(Arrays.toString(array2)); } }
运行结果:
结果分析:
array2[0] = 11不会影响array1[0]的值,此时叫做深拷贝。
array2[0] = 88,会不会影响array1[0]的值?
从上面的图可以看出,数组里面也是可以存地址的,有点类似c语言里面的指针数组,是一个数组,但是里面存放的是地址。
array1中存放的是地址,这个地址又指向了另外一块空间,当对array1克隆拷贝的时候,其实拷贝的是地址,这个地址指向跟array存放的地址的指向同时指向一块空间,如果对array2[0]里面的值做修改,其实是改变的是array1[0]中的地址指向的那块空间里面存放的数值,因为它们都是指向的同一块空间。
如果通过array2[0]去访问那块空间把值修改为88,那么通过array1[0]区访问那块空间的值也会收到影响,我们把这个过程叫做浅拷贝。
没有关系,那跟什么有关系呢?
和代码的实现有关系,从下面图来分析:
如果我们拷贝的是array1[0]中指向那块空间的数值,此时array2[0]里面会存放一个新的地址,指向刚刚拷贝过来的数值,当再对array2[0]赋值时候,array1[0]不会受到影响,因为此时都是指向的不同空间,此时叫做深拷贝。
所以,深拷贝跟浅拷贝跟我们写的代码有关系,跟是不是for循环拷贝没有任何关系。