在Effective Java,2nd Edition,Item 11中,可以找到以下深层复制示例:
public class HashTable implements Cloneable {
private Entry[] buckets = ...;
private static class Entry {
final Object key;
Object value;
Entry next;
Entry(Object key, Object value, Entry next) {
this.key = key;
this.value = value;
this.next = next;
}
// Recursively copy the linked list headed by this Entry
Entry deepCopy() {
return new Entry(key, value,
next == null ? null : next.deepCopy());
}
}
@Override public HashTable clone() {
try {
HashTable result = (HashTable) super.clone();
result.buckets = new Entry[buckets.length];
for (int i = 0; i < buckets.length; i++)
if (buckets[i] != null)
result.buckets[i] = buckets[i].deepCopy();
return result;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
}
}
我不明白这是如何进行深层复制的:键和值是对象,因此没有原始类型。所以据我所知,使用
// Recursively copy the linked list headed by this Entry
Entry deepCopy() {
return new Entry(key, value,
next == null ? null : next.deepCopy());
}
创建一个新的Entry
,其中引用了原始Entry
的键和值?
深层复制本质上是不是意味着:直到达到基本类型,然后将它们复制到克隆?
感谢您提供任何暗示!
答案 0 :(得分:5)
这是一个“深层复制”,原始对象的链接列表(通过next
)的更改将不会在副本中看到,反之亦然。将其与“浅拷贝”进行比较,如果新对象刚刚复制了原始next
参考,将会采取“浅拷贝”。
就密钥和价值而言,它是一个浅层副本 - 如果这些是可变类型并且是变异然后是,则可以通过原始版本和“克隆”版本看到变异。
所以最终,它比天真的“复制所有引用”方法更深层次 - 但它不是完全深层复制。
答案 1 :(得分:1)
创建深层副本时,在新的HashTable中使用“相同”条目是不够的。您必须为每个条目创建新实例。否则,每个表将保存对同一条目对象的引用。然后,当有人修改第一个表中的值时,它也将在secon表(新副本)中修改。