Java数组的深拷贝和浅拷贝

Java数组的存储方式

不同于基本数据类型,Java中的数组是一种引用类型。而在JVM中,栈内存存储变量,堆内存中存储变量值。

一维数组的存储

Java数组的深拷贝和浅拷贝_第1张图片
如图所示,JVM的栈内存中存储一个 I n t e g e r Integer Integer类型的数组变量 a a a,该引用指向堆内存中的一块连续空间@4d41cee,该内存存储数组变量的值。

举例:

Integer [] a = {1,2,3};
System.out.println(a);

在这里插入图片描述

根据结果可以看出,变量 a a a指向内存中的一个固定区域。

二维数组的存储

Java中所有数组的本质其实都是一维数组,对于二维数组,只是在一维数组中存储了一个数组而已。
Java数组的深拷贝和浅拷贝_第2张图片
举例

Integer [][] c = {{1,2,3},{4,5,6},{7,8,9}};
System.out.println("c[0]:"+c[0]);
System.out.println("c[1]:"+c[1]);
System.out.println("c[0]:"+c[2]);

Java数组的深拷贝和浅拷贝_第3张图片

Java二维数组的每一个元素中存储的都是一个内存地址,该内存地址指向一个一维数组。

浅拷贝

浅拷贝指的是,在拷贝时,只是拷贝数组的内存地址,而非数组的实际值。

由于拷贝的是内存地址,浅拷贝会导致一个问题,在改变拷贝值时,原数组的值也会随之改变,因为二者指向同一块内存区域。

举例:

Integer [] a = {1,2,3};
Integer [] b = a;
System.out.println(a);
System.out.println("修改前的b:"+Arrays.toString(b));
b[0] = 0;
System.out.println("修改数组第一个元素后:");
System.out.println("修改后的b:"+Arrays.toString(b));
System.out.println("修改后的a:"+Arrays.toString(a));

Java数组的深拷贝和浅拷贝_第4张图片

通过 ‘=’ 实现浅复制,改变复制值 b b b的第一个值 b [ 0 ] b[0] b[0]后,原始数组 a [ 0 ] a[0] a[0]也随之改变,因为二者指向同一个内存地址,大家可以自行打印数组的内存地址进行确认。

深拷贝

深拷贝指的是,在拷贝时,拷贝数组的每一个值,而非数组在内存中的地址。

深拷贝则相反,由于拷贝的实际值,在改变拷贝值时,不会影响原始数组中的值,因为原始值和拷贝值分别指向两个不同的内存地址。

Integer [] a = {1,2,3};
Integer [] b = Arrays.copyOf(a,a.length);
System.out.println(a);
System.out.println("修改前的b:"+Arrays.toString(b));
b[0] = 0;
System.out.println("修改数组第一个元素后:");
System.out.println("修改后的b:"+Arrays.toString(b));
System.out.println("修改后的a:"+Arrays.toString(a));

Java数组的深拷贝和浅拷贝_第5张图片

通过 A r r a y s . c o p y O f ( a , a . l e n g t h ) Arrays.copyOf(a,a.length) Arrays.copyOf(a,a.length)实现深拷贝,将原始数组的每一个值都拷贝给一个新数组。在改变新数组的值时,原始数组的值不会受到影响。

深拷贝和浅拷贝的实现方式

深拷贝(拷贝值):

方式一:Arrays.copyOf(a,a.length);
方式二:b[i] = a[i];
方式三:b = a.clone();
方式四:System.arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

其中,如果数组是二维数组,需要对每一个子数组进行操作,对一维数组则直接操作。

浅拷贝(拷贝地址):

实现方式:=

你可能感兴趣的:(Java,java,jvm,开发语言)