3

I am having difficulties understanding the concept of "deep copy" in Java.

Assuming I had a class "myClass" with various parameters in it. I tried writing a method "copy" which was supposed to return a deep copy of such class as:

public myClass copy() {

    myClass deepCopy = new myClass();
    deepCopy.varA = varA;
    deepCopy.varB = varB;
    return deepCopy;

}

Can somebody confirm whether this is indeed "deep copying" or if I am doing something wrong?

Thanks!

MrD
  • 4,986
  • 11
  • 48
  • 90
  • http://en.wikipedia.org/wiki/Clone_%28Java_method%29 – G-Man Mar 22 '13 at 13:07
  • And you better use classnames starting with capital letter. – Erik Kaju Mar 22 '13 at 13:08
  • @Kent: But the best solution to that suggests the use of a constructor, whereas I need a method called copy (I am extending an abstract class)@G-Man: – MrD Mar 22 '13 at 13:30
  • @DarioPanada you can implement Cloneable, of course not only`myClass` but also the classes of `varA,B`. you have to handle collection case in your clone methods. – Kent Mar 22 '13 at 13:40

6 Answers6

1

If you don’t want to implement deep copy yourselves then you can go for serialization. It does implements deep copy implicitly and gracefully handling cyclic dependencies.

A nice article about Deep Copy, Clone and Shallow Copy can be found here.

Joetjah
  • 6,292
  • 8
  • 55
  • 90
0

Only If:

  • Class "myClass" only contains varA and varB.
  • Class "myClass" has no superclass.
  • Variables varA and varB are of an elementary type (ie. String, int, long, ....). Otherwise you'll have to apply the same copying process to them too.
Jan Goyvaerts
  • 2,913
  • 4
  • 35
  • 48
0

In deep copy When the copied object contains some other object its references are copied recursively

see more at here

Sharique Ansari
  • 1,458
  • 1
  • 12
  • 22
0

A deep copy occurs when an object is copied along with the objects to which it refers.

If suppose there is a MainObject1 of MainObject type having fields "field1" of int type, and "ContainObject1" of ContainObject type. When you do a deep copy of MainObject1, MainObject2 is created with "field3" containing the copied value of "field1" and "ContainObject2" containing the copied value of ContainObject1. So any changes made to ContainObject1 in MainObject1 will not be reflected in MainObject2.

In your implementation, if you are trying to simulate deep copy, then you should have only these two variables : varA and varB in your class of primitive type.

Divya Motiwala
  • 1,659
  • 1
  • 16
  • 24
0

This would only be a deep copy if varA and VarB were primitive types. If they are reference types than your new object will point at the same instances of these classes as the original.

An easy way to implement deep copy is via serialization. Apache commons lang provides a utility method for this (SerializationUtils.clone( foo ) ).

It does however requires that all the objects are serializable.

If this is not the case for you XStream can be used for deep cloning with minimal development effort.

http://x-stream.github.io/

Sanoj Kashyap
  • 5,020
  • 4
  • 49
  • 75
henry
  • 5,923
  • 29
  • 46
-1

Observe output of following program.
1> See output without clone() method. Remove clone() method from following program. (example of shallow copy)
2> See output with clone() method. (Example Deep copy. See ArrayList object's output)

import java.util.ArrayList;
import java.util.List;

public class DeepCopy implements Cloneable {
    private List<String> hobbiesList;
    private int age;
    private String name;
    private float salary;

    public static void main(String[] args) throws CloneNotSupportedException {
        DeepCopy  original = new DeepCopy();
        original.name="AAA";
        original.age=20;
        original.salary=10000;
        original.hobbiesList = new ArrayList<String>();
        original.hobbiesList.add("Cricket");
        original.hobbiesList.add("Movies");
        original.hobbiesList.add("Guitar");
        original.hobbiesList.add("Eating");

        DeepCopy  cloned = (DeepCopy) original.clone();
        System.out.println("original:="+original);
        System.out.println("cloned  :="+cloned);
        System.out.println("After adding two more hobbies in 'original' which untimately reflected in 'cloned'");
        cloned.name="BBB";
        cloned.age=27;
        cloned.salary=18237;
        cloned.hobbiesList.add("Trecking");
        System.out.println("original       :="+original);
        System.out.println("cloned  changed:="+cloned);
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        DeepCopy clone = (DeepCopy)super.clone();
        clone.hobbiesList = new ArrayList<String>(clone.hobbiesList);
        return clone;
    }
    @Override
    public String toString() {
        return "My name is (String)"+name + " having age (int)"+age+". I earned (float)"+salary+" and hobbies are (ArrayList)"+hobbiesList;
    }
}
AmitG
  • 10,365
  • 5
  • 31
  • 52
  • Could the method be called copy? – MrD Mar 22 '13 at 13:32
  • clone() inherited method from Object class does deep copy implicitly for the variable such as int, long, boolean except for some other class like ArrayList (example). So it is better to use clone() method (class should implement Cloneable interface) to avoid coding by ourselves. In above my given answer you have to override clone() in those cases where you stuck in ArrayList kind of object which are not deep copied by clone() method. So override clone() method and do some coding to copy again those ArrayList object and its contents. – AmitG Mar 22 '13 at 13:37