I have classes which aim to contain many attributes of different types. I would want to automatically deep clone all of them rather than writing an instruction for each of them:
class AttributesContainer implements Cloneable {
Type1 a1 = new Type1(...), a2 = new Type1(...);
Type2 b1 = new Type2(...);
...
public AttributesContainer clone() {
AttributesContainer ac = (AttributesContainer) super.clone();
// Regroup that like using a loop
ac.a1 = a1.clone();
ac.a2 = a2.clone();
ac.b1 = b1.clone();
...
return ac;
}
}
I have thought about adding the fields in a table each time but I could not change the reference of the fields:
class ContainerAbstract implements Cloneable {
public <T> T add(T t) {
// adds the reference into a list
return t;
}
public ContainerAbstract clone() {
ContainerAbstract ca = (ContainerAbstract) super.clone();
// copy the attributes
return ca;
}
}
class AttributesContainer extends ContainerAbstract implements Cloneable {
Type1 a1 = add(new Type1(...)), a2 = add(new Type1(...));
Type2 b1 = add(new Type2(...));
...
public AttributesContainer clone() {
AttributesContainer ac = (AttributesContainer) super.clone();
return ac;
}
}
I have also thought that I could return a wrapper in the add() method but it would introduce an extra method get() to call each time I want to access an attribute:
AttributesContainer ac = new AttributesContainer();
ac.get()...;
It there a way to change the fields to there source, like we could achieve that in C using a pointer?
NB: I already checked Copy fields between similar classes in java, How do you make a deep copy of an object in Java? and http://www.java2s.com/Tutorial/Java/0125__Reflection/Returnalistofallfieldswhateveraccessstatusandonwhateversuperclasstheyweredefinedthatcanbefoundonthisclass.htm.
EDIT: One of the reasons I don't use the serialization is that in fact, I have a final property for which I just want a fresh new instance.
I thought about making it transient and then giving it a new object but I can't, since it is final:
class A {
private Double d = new Double(2);
public final transient B b = new B();
public A copy() {
A a = (A) DeepCopy.copy(this);
a.b = new B(); // Error, b is final
return a;
}
}