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)。