Java clone()方法是否必须克隆对象中所有级别的所有引用?
在Java中重写Java clone()方法是否必须克隆对象中所有级别的所有引用?,java,clone,Java,Clone,在Java中重写clone()方法时,我们需要确保克隆的对象不会影响原始对象,因此对原始对象内部实例的引用也必须克隆,而不是简单地复制 在《有效Java》一书中,我发现了以下示例: class HashTable implements Cloneable{ private Entry[] buckets; // ... private static class Entry{ Object key; Object value;
clone()
方法时,我们需要确保克隆的对象不会影响原始对象,因此对原始对象内部实例的引用也必须克隆,而不是简单地复制
在《有效Java》一书中,我发现了以下示例:
class HashTable implements Cloneable{
private Entry[] buckets;
// ...
private static class Entry{
Object key;
Object value;
Entry next;
Entry(Object key, Object value, Entry next){
this.key = key;
this.value = value;
this.next = next;
}
Entry deepCopy(){
return new Entry(key, value,
next == null ?
null :
next.deepCopy());
}
}
@Override
public Object clone() throws CloneNotSupportedException{
HashTable result = (HashTable) super.clone();
result.buckets = new Entry[buckets.length];
for(int i=0; i<buckets.length; i++){
if(buckets!=null){
result.buckets[i] = buckets[i].deepCopy();
}
}
return result;
}
// ...
}
然后它在bucket中循环,并对bucket
数组中的所有元素进行深度复制:
for(int i=0; i<buckets.length; i++){
if(buckets!=null){
result.buckets[i] = buckets[i].deepCopy();
}
}
for(int i=0;i
由于我们没有克隆克隆对象的“克隆”项的键和值,它们将指向相同的对象。这意味着可以更改克隆版本中的一个值引用并影响原始对象
这是合法的,因为Java集合的语义是它们存储引用;因此,具有相同引用的新集合是原始集合的有效副本。好吧……事实上,这取决于要克隆的对象。集合类型如所述的哈希表
(或者像LinkedList
)这样的其他元素只能克隆它们的内部结构。你不知道元素的类型是否也可以克隆!我想说,你可以从有效的Java中学到的最相关的一课是“考虑到与可克隆性相关的所有问题,新接口不应扩展它,新的可扩展类不应实现它。[…]通常,复制功能由构造函数或工厂提供。”@daniu克隆技术(克隆、复制构造函数、工厂方法等)与问题的重点无关:集合的元素如何?它要求一个一般概念。
for(int i=0; i<buckets.length; i++){
if(buckets!=null){
result.buckets[i] = buckets[i].deepCopy();
}
}