Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java clone()方法是否必须克隆对象中所有级别的所有引用?_Java_Clone - Fatal编程技术网

Java clone()方法是否必须克隆对象中所有级别的所有引用?

Java clone()方法是否必须克隆对象中所有级别的所有引用?,java,clone,Java,Clone,在Java中重写clone()方法时,我们需要确保克隆的对象不会影响原始对象,因此对原始对象内部实例的引用也必须克隆,而不是简单地复制 在《有效Java》一书中,我发现了以下示例: class HashTable implements Cloneable{ private Entry[] buckets; // ... private static class Entry{ Object key; Object value;

在Java中重写
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();
    }
}