0

I'm trying to clone an instance of a custom class I made called CSP. I have one instance called csp and I want to make a clone of csp called cspclone. Here is what I'm using to do that:

CSP cspclone = new CSP((csp.x).clone(), (csp.d).clone(), (csp.c).clone());

For some reason though when I pass cspclone to a method that modifies it csp gets modified also as if I forgot the .clone() functions but I didn't! Why is this happening?!

Kyle V.
  • 4,752
  • 9
  • 47
  • 81

4 Answers4

3

Override the clone method in CSP:

public class CSP {
    private String aField;
    private int[] array;
    private int[][] twoDArr;
    private List<ALContent> list; //here ALContent also needs to override clone properly

    @Override
    public Object clone() {
        CSP clone = new CSP();
        clone.aField = this.aField;
        clone.array = new int[this.array.length];
        System.arraycopy(this.array, 0, clone.array, 0, this.array.length);

        clone.list = new ArrayList<ALContent>();
        for(ALContent content : this.list) {
            clone.list.add(content.clone()); //make sure you add the clone of the content
        }

        clone.twoDArr = new int[this.twoDArr.length][];
        for(int i=0; i<this.twoDArr.length; i++) {
            clone.twoDArr[i] = new int[this.twoDArr[i].length];
            System.arraycopy(this.twoDArr[i], 0, clone.twoDArr[i], 0, this.twoDArr[i].length);
        }

        return clone;
    }
}

Then you can do:

CSP csp = new CSP();
CSP cspClone = (CSP) csp.clone();
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
  • So what goes where the `//...` is? – Kyle V. Nov 16 '11 at 22:17
  • Ok, so how would I do it for non-arrays? Here are the fields of a CSP object: `public int[] x; public ArrayList d[]; public int[][] c;` – Kyle V. Nov 16 '11 at 22:28
  • The default implementation of the `clone` in `ArrayList` does shallow copy: http://download.oracle.com/javase/6/docs/api/java/util/ArrayList.html#clone%28%29. So, you have to do it manully: http://stackoverflow.com/questions/715650/how-to-clone-arraylist-and-also-clone-its-contents. – Bhesh Gurung Nov 16 '11 at 22:35
  • @StickFigs: Updated the answer again. – Bhesh Gurung Nov 16 '11 at 22:40
  • @StickFigs: For int[][], check this out: http://stackoverflow.com/questions/5563157/how-to-deep-copy-2-dimensional-array-different-row-sizes – Bhesh Gurung Nov 16 '11 at 22:55
  • @StickFigs: See the update for the 2 dimensional array int[][]. – Bhesh Gurung Nov 16 '11 at 23:04
0

If your properties of array type use System.arraycopy

mishadoff
  • 10,719
  • 2
  • 33
  • 55
0

According to http://download.oracle.com/javase/1.3/docs/api/java/lang/Object.html#clone%28%29

this method creates a new instance of the class of this object and initializes all its fields with exactly the contents of the corresponding fields of this object, as if by assignment; the contents of the fields are not themselves cloned. Thus, this method performs a "shallow copy" of this object, not a "deep copy" operation.

You might have to override the clone method and clone() a reference type attribute within the object (i.e., perform deep copy operation).

wannik
  • 12,212
  • 11
  • 46
  • 58
0

To solve your problem you need deep cloning. The default clone method does a shallow copy. See Object.clone().

Here are some approaches. All have advantages and drawbacks.

Here are several other stackoverflow discussions of cloning.

Community
  • 1
  • 1
Richard Povinelli
  • 1,419
  • 1
  • 14
  • 28