我正在攻读java考试,我发现的实际上与理论教学不同。
以下是代码:
StringBuilder num3[]= new StringBuilder[2];
num3[0]= new StringBuilder("Pine");
num3[1]= new StringBuilder("Oak");
StringBuilder num4[] = new StringBuilder[2];
System.arraycopy(num3, 0, num4, 0, 2);
System.out.println(num3[0]==num4[0]);
System.out.println(num4[0]);
num3[0] = new StringBuilder("Choc");
System.out.println(num3[0]);
System.out.println(num4[0]);
输出结果为:
true Pine Choc Pine
真实的陈述表明它是浅拷贝,因为num4 [0]引用num3 [0]的相同对象。但是当我更改num3 [0]时,我预期num4 [0]也会改变。
如果它是一个浅层副本,为什么会这样?
是因为为num3 [0]创建了新对象而num4数组正在引用旧的“Pine”StringBuilder对象吗?
如果是这样,有人能给我一个System.arraycopy的例子吗?这个浅拷贝很明显?
提前致谢, Chrisyopher
答案 0 :(得分:7)
在System.arraycopy
之后,两个数组确实是彼此的浅拷贝。也就是说,您有{em>引用的副本到StringBuilder
。引用的对象是相同的。
num3: [ refA, refB ] num4: [ refA, refB ]
| | | |
| `-------> StringBuilder("Oak") <-------+-----'
`------------> StringBuilder("Pine") <------'
但是,您将num3[0]
中的引用更改为指向新的StringBuilder
:
num3: [ refC, refB ] num4: [ refA, refB ]
| | | |
| `-------> StringBuilder("Oak") <-------+-----'
| StringBuilder("Pine") <------'
`------------> StringBuilder("Choc")
基础对象没有改变。你所做的一切都改变了引用它们的内容。
System.arraycopy
就像有一个for
循环复制数组中的值,除了它对大型数组更有效(因为现代CPU有大量内存复制的特殊指令)。你根本不需要它语义;这只是一次性能优化。
答案 1 :(得分:1)
num3[0]
和num4[0]
是对同一对象的引用,因此当您更改num3[0]
时,它只会更改num3[0]
指向的位置,而不会更改num4[0]
1}}指向。
System.out.println(num3[0]==num4[0]);
返回true,因为两者都指向同一个对象,但两者都是个体。
如果你做了类似
的事情 num3[0].append("something")
然后你会打印num3[0]
和num4[0]
然后两者都会受到影响。
答案 2 :(得分:1)
您没有更改num3 [0],而是将其指向其他内容,即新的StringBuilder对象。 num3 [0]和num4 [0]不再指向同一个对象,因此num4 [0]不会改变。将复制数组引用的值,但如果您修改这些值,则不会影响其他数组。如果您修改它们所指向的对象,而不是引用来修改这些对象,会对它产生什么影响。
将num3[0]
和num4[0]
视为指向行李包的两个人。
如果你在背包里添加东西,它们都会指向已经改变的东西。但是,如果您要求num3[0]
指向电视,则num4 [0]仍将指向背包。
答案 3 :(得分:1)
是因为正在为num3 [0]和旧的创建新对象 “Pine”StringBuilder对象是由num4数组引用的?
完全。
如果是这样,有人能给我一个System.arraycopy的例子吗?这个浅拷贝很明显?
我不确定我是否理解这个问题。没有副本,无论是浅的还是深的,都会对你在副本后做什么产生影响。
但请尝试以下方法:
num3[1].append("tree");
println(num4[1]); // should be "Oaktree"
答案 4 :(得分:0)
在这种情况下,浅表副本只不过是对该对象的新引用。
您有一个对象Pine
,其中一个指针存储在int num3
中。现在,您创建一个存储在num4
中的浅表副本(您创建一个新引用)。您现在有一个带有两个引用的Pine
对象。当您将Choc
分配给num3
时,引用数量会减少1,并且您有效地将num3
所持有的引用替换为另一个引用。 Pine
从未改变过任何方式。