gpt4 book ai didi

java - 深度克隆,同时保留对可变对象的共享引用

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:37:33 25 4
gpt4 key购买 nike

我通过在此类及其构成它的整个字段层次结构中实现 clone() 来深度克隆某个类的实例。在我放入这些类的 clone() 实现中,我通过在原始实例的相应字段上调用 ​​clone() 来分配新实例的每个字段(这个)。然后我就在主类上调用 clone()。我相信这是一种非常标准的深度克隆方式。

下面是一个可运行的小例子。我得到的克隆是一个真正的深拷贝,其中每个字段和子字段中包含的对象都是新对象,与原始实例中的对应对象相同。

但这意味着如果在原始字段中 ab 引用同一个对象 X,在深度克隆中它们将不会引用同一个对象( X 的克隆);相反,它们将引用 X 的两个不同克隆。

所以我想通过深度克隆对象在其整个层次结构中的所有字段来深度克隆一个对象,但是如果层次结构在多个字段中包含相同的引用,则只有这些字段中的一个应该被深度克隆到一个新对象;其他字段将只引用这个新对象。

它看起来不像一个简单的解决方案的问题,但我想知道是否存在某种技术,或者是否有某种工具或库可以做到这一点。

TestClone.java

public class TestClone {

public static void main(String[] args) throws CloneNotSupportedException {

// Create the object to share :

SharedObject shared = new SharedObject(1);

// Create the object to clone, which will own two Holder instances
// both holding a reference to *the same* object :

MainObject original = new MainObject(new Holder(shared), new Holder(shared));

// Show that both holders hold a reference to the same object :

System.out.println("Original holder1 holds " + original.holder1.field.hashCode());
System.out.println("Original holder2 holds " + original.holder2.field.hashCode());

// Deep-clone the main object :

MainObject cloned = (MainObject) original.clone();

// Show that the two cloned holders now hold a reference to *different* cloned objects :

System.err.println("Cloned holder1 holds " + cloned.holder1.field.hashCode());
System.err.println("Cloned holder2 holds " + cloned.holder2.field.hashCode());

// How to clone so that they will hold a reference to *the same* cloned object ?
}

}

SharedObject.java

public class SharedObject implements Cloneable {

public int n;

public SharedObject(int n) {

this.n = n;
}

@Override
protected Object clone() throws CloneNotSupportedException {

SharedObject clone = (SharedObject) super.clone();

clone.n = this.n;

return clone;
}

}

持有人.java

public class Holder implements Cloneable {

public SharedObject field;

public Holder(SharedObject field) {

this.field = field;
}

@Override
protected Object clone() throws CloneNotSupportedException {

Holder clone = (Holder) super.clone();

clone.field = (SharedObject) this.field.clone();

return clone;
}

}

MainObject.java

public class MainObject implements Cloneable {

public Holder holder1;

public Holder holder2;

public MainObject(Holder holder1, Holder holder2) {

this.holder1 = holder1;

this.holder2 = holder2;
}

@Override
protected Object clone() throws CloneNotSupportedException {

MainObject clone = (MainObject) super.clone();

clone.holder1 = (Holder) this.holder1.clone();

clone.holder2 = (Holder) this.holder2.clone();

return clone;
}

}

最佳答案

没有这种克隆操作的“标准”方式。此外,我不知道有任何库支持它。

您的真正要求是构建从原始对象到克隆对象的一对一映射(双射)。

一种技术是首先通过克隆每个对象(如果它不在 map 中)来建立这样的层次结构,一旦在您的根对象上调用了克隆方法。然后,在新的克隆层次结构中组装引用。

顺便说一句,Java 中的序列化技术已经实现了该技术。让所有类都实现Serializable,然后将根对象写入ObjectOutputStreampipe it to an ObjectInputStream ,然后反序列化所有对象。序列化机制会满足您的要求。

关于java - 深度克隆,同时保留对可变对象的共享引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39191522/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com