Java System.arraycopy()带基元和对象引用的浅拷贝或深拷贝
我在某个地方读到,Java System.arraycopy()带基元和对象引用的浅拷贝或深拷贝,java,arrays,deep-copy,shallow-copy,Java,Arrays,Deep Copy,Shallow Copy,我在某个地方读到,System.arraycopy确实为基本数据类型创建了一个新副本,为对象引用创建了浅层副本 所以,我用下面的代码开始了这个实验 //trying with primitive values int a[] ={1,2,3}; int b[] = new int[a.length]; System.arraycopy(a,0,b,0,a.length); b[0] = 9; System.out.println(Arrays.toString(a)); System.out.p
System.arraycopy
确实为基本数据类型创建了一个新副本,为对象引用创建了浅层副本
所以,我用下面的代码开始了这个实验
//trying with primitive values
int a[] ={1,2,3};
int b[] = new int[a.length];
System.arraycopy(a,0,b,0,a.length);
b[0] = 9;
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(b));
//now trying with object references
Object[] obj1 = {new Integer(3),new StringBuffer("hello")};
Object[] obj2 = new Object[obj1.length];
System.arraycopy(obj1,0,obj2,0,obj1.length);
obj1[1] = new StringBuffer("world");
System.out.println(Arrays.toString(obj1));
System.out.println(Arrays.toString(obj2));
结果是
[1, 2, 3]
[9, 2, 3]
[3, world]
[3, hello]
但我所期望的是
[1, 2, 3]
[9, 2, 3]
[3, world]
[3, world]
从上面的代码中,我了解到,System.arraycopy
对对象引用进行深度复制
如果是这样,那么
obj1[0]==obj2[0]
如何给出true
系统。arraycopy
进行浅层复制,这意味着它在应用于非基元数组时复制对象
引用
因此在System.arraycopy(obj1,0,obj2,0,obj1.length)之后
,obj1[0]==obj2[0]
和obj1[1]==obj2[1]
,因为两个数组都持有对同一对象的引用
将新值分配给obj1[1]
后,obj1[1]
不再引用与obj2[1]
相同的StringBuffer
实例。这就是为什么Arrays.toString(obj1)
和Arrays.toString(obj2)
的输出是不同的
如果代替
obj1[1] = new StringBuffer("world");
你会写信吗
obj1[1].setLength(0);
obj1[1].append("world");
两个print语句都将输出[3,world]
,因为两个数组仍然引用相同的StringBuffer
实例。否,这是供参考的浅拷贝
首先创建对新StringBuffer(“hello”)
的引用,然后创建该引用的浅层副本。因此,您有1个StringBuffer
,但有2个对它的引用
最后,将另一个引用替换为一个全新的StringBuffer(“world”)
我知道System.arraycopy对对象进行深度复制
参考如果是,obj1[0]==obj2[0]如何给出真值
不,你错了,它不执行深度复制。由于obj1[0]==obj2[0]
在两个数组中引用了相同的整数对象(即,索引“0”处数组中存储的引用),因此您得到的答案为true
。此外,您还可以比较返回false
的obj1[1]==obj2[1]
,因为这两个StringBuffer
引用不同
另外,另一点是,
System.arrayCopy
只进行浅层复制(简单地将引用/值从一个数组复制到另一个数组),您可以参考这一点。您有一个误解
一旦你做到了
obj1[1] = new StringBuffer("world");
您已替换了obj1[1]
中的引用。现在,这两个数组包含对不同对象的不同引用
如果要查看复制的是实际引用,则应尝试:
obj1[1].setLength(3);
现在
obj1[1]
和obj2[1]
都应该包含字符串hel
,因为您没有替换引用,而是更改了内容。“原语的深度复制”。如果根据定义,原语没有引用任何更深层的内容,那么如何对原语进行深层复制呢?如果是这样的话obj1==obj2
应该正确吗?但是它给出的是false
不,它们不是对同一数组的引用,因此当然返回false。obj1[0]==obj2[0]比较整数值
-实际上这是错误的obj1[0]
和obj2[0]
引用相同的Integer
对象作为arraycopy语句的结果,这就是obj1[0]==obj2[0]
的原因。如果添加一个obj2[0]=新整数(3)
在arraycopy语句之后,obj1[0]==obj2[0]
将不再为真,即使两者仍然具有相同的值(3)。