I have an object (not SObject!) with a member of type List, when I clone the object and add something to the list, the original record will also be modified:
public class ThingToClone {
public List<Integer> values = new List<Integer>();
}
ThingToClone original = new ThingToClone();
ThingToClone clone = original.clone();
clone.values.add(1);
System.debug(LoggingLevel.ERROR, original);
results in
12:04:15:022 USER_DEBUG [5]|ERROR|ThingToClone:[values=(1)]
This is not what I expected, and I was not able to find any "Apex Object" documentation. Is there something like that? All I found was SObject related.
Edit:
To see if it creates a shadow object, I also tried to modify a class member, that was not part of the list. called it Integer anyNumber
ThingToClone original = new ThingToClone();
ThingToClone clone = original.clone();
clone.values.add(1);
clone.anyNumber = 2;
original.anyNumber = 3;
The new debug result is something really strange:
System.debug(LoggingLevel.ERROR, clone);
System.debug(LoggingLevel.ERROR, original);
USER_DEBUG [6]|ERROR|ThingToClone:[anyNumber=2, values=(1)]
USER_DEBUG [7]|ERROR|ThingToClone:[anyNumber=3, values=(1)]
So it's clearly not the same(shadow) object
Best Answer
I disagree and say it works as expected. My assumption is that Apex
clone()
uses Java'sclone()
internally. Java'sclone()
is a shallow clone, meaning the list inThingToClone
will just point to the original objects list.As described here (http://howtodoinjava.com/core-java/cloning/a-guide-to-object-cloning-in-java/#deep_cloning):
So I guess @IllusiveBrain is right in his comment, where he states that
clone()
copies primitive variables by value and non-primitive variables by reference. I'd expect this to be NO platform bug but intended behavior.