Object clone does not work as expected

Initially, I thought that clone() creates shallow copy of the Original and a pointer to the original one.

I tried the following to support my argument

public class ThingToClone {
    public List<Integer> values = new List<Integer>();    
}

ThingToClone original = new ThingToClone();
ThingToClone clone = original.clone();
ThingToClone clone_of_clone = clone.clone();
clone.values.add(1);
original.values.add(2);

System.debug(LoggingLevel.ERROR, 'Original Instance:' + original);
System.debug(LoggingLevel.ERROR, 'Clone of  Original:' +clone);
System.debug(LoggingLevel.ERROR, 'Clone of clone :' + clone_of_clone);

Debug log proves all cloned object instances of wrapper class, have the same values

Debug log

06:17:02.1 (4199907)|USER_DEBUG|[11]|ERROR|Original Instance:ThingToClone:[values=(1, 2)]
06:17:02.1 (4310866)|USER_DEBUG|[12]|ERROR|Clone of  Original:ThingToClone:[values=(1, 2)]
06:17:02.1 (4410739)|USER_DEBUG|[13]|ERROR|Clone of clone :ThingToClone:[values=(1, 2)]

A similar question is also present on SFSE, that might help you investigate further.

EDIT

With the recent turn of events, I played around a bit and found workaround to your problem.

Updated code

public class ThingToClone {
    public List<Integer> values;    
    public integer testInt;
    public Account acc;
}

ThingToClone original = new ThingToClone();
ThingToClone clone = original.clone();
ThingToClone clone_of_clone = clone.clone();

// integer member
original.testInt = 20;
clone.testInt = 2;

// sobject member
Account testAcc = new Account(Name = 'Test Account');
clone.acc = testAcc;

// collection member
clone.values = new List<integer>();
clone.values.add(1);
original.values = new List<integer>();
original.values.add(2);

System.debug(LoggingLevel.ERROR, 'Original Instance:' + original);
System.debug(LoggingLevel.ERROR, 'Clone of  Original:' +clone);
System.debug(LoggingLevel.ERROR, 'Clone of clone :' + clone_of_clone);

Updated debug log

07:19:35.1 (4421596)|USER_DEBUG|[22]|ERROR|Original Instance:ThingToClone:[acc=null, testInt=20, values=(2)]
07:19:35.1 (4743354)|USER_DEBUG|[23]|ERROR|Clone of Original:ThingToClone:[acc=Account:{Name=Test Account}, testInt=2, values=(1)]
07:19:35.1 (4864965)|USER_DEBUG|[24]|ERROR|Clone of clone :ThingToClone:[acc=null, testInt=null, values=null]

Explanation

If I don't create the instance of the List<> in the wrapper class, instead create them after cloning the object, then the Values are preserved. I know, that other member types are getting expected response, but this is just a workaround that I found to get you on the move, if you are stuck.

Tags:

Clone

Apex

Bug