1 2 Previous Next 18 Replies Latest reply: Jul 16, 2007 8:39 AM by 800323 RSS

    All about Deep /Shallow copy

    807605
      Hi,

      I have a hierarchycal data structure, I want to have two copies, where one copy remains untouched and other copy goes through amendments,

      How can I create such two copies, I guess I refer to deep copy.

      If so how can I make a deep copy.

      The structure consists of dtos, arrays etc

      Thanks,
        • 1. Re: All about Deep /Shallow copy
          796440
          Create a new object of the same class.

          All mutable objects referred to by member variables (or objects that you can't be sure won't be externaly mutated) need to be deep copies of their originals.

          Primitives and references to immutable objects (or objects you can be sure won't be externally mutated) need not be deep copied (and in fact, deep copy means nothing for primitives).
          • 2. Re: All about Deep /Shallow copy
            807605
            All classes inherit a clone() function by default. try calling this and seeing if it returns what you want (it returns an Object, which your calling routine will have to cast into the same class type as your class). If not, override the function with your own definition (using the same function signature) where the other advice about what objects (primitives) dont need a deep clone and which do. If you dont understand what I'm saying, look up 'java clone' for examples.
            • 3. Re: All about Deep /Shallow copy
              796440
              A copy constructor is generally considered a better approach than the clone method. The disadvantage of the copy constructor is you have to know at compile time which class you have, or muck about with reflection.
              • 4. Re: All about Deep /Shallow copy
                807605
                A copy constructor is generally considered a better
                approach than the clone method. The disadvantage of
                the copy constructor is you have to know at compile
                time which class you have, or muck about with
                reflection.
                Pardon my ignorance, but what are the advantages of the copy method?

                Thanks /Pete
                • 5. Re: All about Deep /Shallow copy
                  796440
                  Pardon my ignorance, but what are the advantages of
                  the copy method?
                  http://www.javapractices.com/Topic71.cjp
                  • 6. Re: All about Deep /Shallow copy
                    807605
                    Got it. Thanks. So copy constructor is what is called for in this case since you have a specific object to copy....

                    again, thanks
                    • 7. Re: All about Deep /Shallow copy
                      807605
                      I bit of a warning;

                      I've looked at copy constructor per the previous post: http://www.javapractices.com/Topic12.cjp

                      /** constructor */
                      public Galaxy (double aMass, String aName) {
                      fMass = aMass;
                      fName = aName;
                      }

                      /** Copy constructor. */
                      public Galaxy(Galaxy aGalaxy) {
                      this(aGalaxy.getMass(), aGalaxy.getName());
                      }

                      This assumes ALL class variables in the class are set via the constructor. However, if you have the following, the copy constructor is not adequate:

                      private String name;
                      public void setName(String name){
                      this.name=name;
                      }

                      You will need to change the copy constructor it as follows:
                      /** Copy constructor. */
                      public Galaxy(Galaxy aGalaxy) {
                      this(aGalaxy.getMass(), aGalaxy.getName());
                      this.name= aGalaxy.getName();
                      }

                      That is to say, you will have to set any other class variables not specifically set in the constructor.

                      Buy the way, I like the copy constructor better than clone() because I never liked having the caller cast the return of clone into the correct type.
                      • 8. Re: All about Deep /Shallow copy
                        796440
                        This assumes ALL class variables in the class are set
                        via the constructor.
                        Well, the point of a copy c'tor is to make a new object that has the same state as the original. If you don't do it, that's just a bug in your copy c'tor.
                        • 9. Re: All about Deep /Shallow copy
                          807605
                          this(aGalaxy.getMass(), aGalaxy.getName());
                          What exactly do you thing the second argument is for? Window dressing perhaps.
                          • 10. Re: All about Deep /Shallow copy
                            807605
                            Sorry, me bad. My example should have used a class variable other than name, but you get the idea.
                            • 11. Re: All about Deep /Shallow copy
                              800323
                              Another option is to serialize the object and then unserialize it to a new instance. The disadvantages to this method are that all objects referenced by the main object must be serializable and serialization is not the most efficient method.
                              Using serialization to clone an object may not be considered a GoodThing(TM) � you might what to do a Google search to see if there are other advantages or disadvantages (I recall some article on the subject).
                              • 12. Re: All about Deep /Shallow copy
                                807605
                                A copy constructor is generally considered a better
                                approach than the clone method. The disadvantage of
                                the copy constructor is you have to know at compile
                                time which class you have, or muck about with
                                reflection.
                                I have to disagree with you here (and with the article you referenced later).

                                First, as you noted, with the copy ctor you have to know the object's type beforehand. And if you happen to have an instance of a subclass, you're going to lose all the subclass-specific data.

                                The referenced article claims that "clone is very tricky to implement correctly in all circumstances, nearly to the point of being pathological," but I'd claim that a copy constructor is at least as difficult.

                                In both cases, you have to ensure that all contained mutable objects are correctly copied (deep versus shallow), and that the copy proceeds recursively (for example, if you have a collection, you can't just copy the collection, you have to copy its members as well, and their contents, and so on).

                                Clone also became a little easier to use with 1.5, with the introduction of covariant return types: you no longer need to cast its result.

                                As another poster mentioned, serialization is an easy way to implement a clone() method, although it will be a little too aggressive, creating new instances of immutable objects. On the positive side, it keeps track of objects that appear multiple times in the graph, so will not break any assumptions about identity.

                                I've ended up implementing a clone helper method, which uses reflection to recursively traverse an object graph, copying mutable objects and preserving object identity. It's probably a little faster than using serialization, and seems more correct to me, but took several thousand lines of unit test code to get right.
                                • 13. Re: All about Deep /Shallow copy
                                  796440
                                  To be honest, I've never really understood what the big bad deal was with cloning. I'm just toeing the party line saying the copy c'tors are better. It seems like one of those things I knew at one point but forgot the reasons for.
                                  • 14. Re: All about Deep /Shallow copy
                                    807605
                                    Some things that screw up clone:

                                    Final object fields that need to be copied:
                                    public class WriteMyClone {
                                        private final Mutable field = new Mutable();
                                    }
                                    fields that are instances of inner classes -- how do you update the
                                    reference to the outer instance? This is really final, again.
                                    public class WriteMyClone2 {
                                        class Inner{}
                                    
                                        private Inner field = new Inner();
                                    }
                                    (Here, of course, I want field's WriteMyClone2.this to point to the
                                    outer object that holds this reference.)
                                    1 2 Previous Next