Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/303.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 深度复制应该如何工作?_Java - Fatal编程技术网

Java 深度复制应该如何工作?

Java 深度复制应该如何工作?,java,Java,当进行深度复制时,显然不应复制引用。但是,如果要复制的对象包含本身是对同一对象的引用的对象,则应维护该对象,还是仅复制数据 范例 public class Program() { public void Main(String[] args) { Person person = new Person(); person.setName("Simon"); List<Person> people = new ArrayList&

当进行深度复制时,显然不应复制引用。但是,如果要复制的对象包含本身是对同一对象的引用的对象,则应维护该对象,还是仅复制数据

范例

public class Program() {
    public void Main(String[] args) {
        Person person = new Person();
        person.setName("Simon");

        List<Person> people = new ArrayList<Person>();
        people.add(person);
        people.add(person);
        people.add(person);

        List<Person> otherPeople = magicDeepCopyFunction(people);

        otherPeople.get(0).setName("Adam");

        // should this output 'Adam' or 'Simon'?
        System.out.println(otherPeople.get(1)); 
    }
}
公共类程序(){
公共void Main(字符串[]参数){
Person=新人();
person.setName(“西蒙”);
List people=new ArrayList();
人。添加(人);
人。添加(人);
人。添加(人);
列出其他人=magicDeepCopyFunction(人);
otherPeople.get(0).setName(“Adam”);
//这个输出应该是“Adam”还是“Simon”?
System.out.println(otherPeople.get(1));
}
}

我可以看到两种观点的论据,但我想知道共识是什么。

这取决于您对数据结构工作方式的期望


通常情况下,您会使引用与原始文档中的引用一样常见。i、 它应该假设你有两个对同一个对象的引用。您不应该期望它为同一对象创建两个副本,以解决不正确的数据结构。

真正的深度副本会创建引用树下所有内容的副本

如果B是a的深度副本,则您对a所做的任何更改都不会通过B可见

大多数深度复制算法不会注意到,在您的示例中,
people
的所有三个成员都引用了相同的
person
。典型的深度复制算法将创建三个新的Person对象

然而,看到真正的深度拷贝并不常见,因为它很难可靠地编程(定义非常严格的数据结构除外),而且在运行时成本很高

西蒙+1
如果我看到magicDeepCopyFunction()的调用,我会期待真正的深度复制。它更具防御性,也更难实现,因为可能存在另一个层次的关系、周期等。这实际上取决于您想做什么,但如果您调用方法deep copy,其他人可以把它当作一个没有任何风险的黑匣子来使用。

我认为任何合适的深度复制算法都会保留所有可见对象的缓存并重用它们。序列化也会出现同样的问题,这在序列化算法中是经常发生的。@MarkoTopolnik我接受这一点,并通过暗示“典型”和“大多数”深度复制算法不“体面”来绕开它。)