participate


Java Programming - All about Deep /Shallow copy
<<   Back to Forum  |   Give us Feedback
This topic has 18 replies on 2 pages.    1 | 2 | Next »
lalith123
Posts:40
Registered: 12/3/04
All about Deep /Shallow copy   
Jul 15, 2007 5:48 PM

 
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,
 
jverd
Posts:51,815
Registered: 3/30/99
Re: All about Deep /Shallow copy   
Jul 15, 2007 6:28 PM (reply 1 of 18)  (In reply to original post )

 
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).
 
George123
Posts:273
Registered: 6/25/07
Re: All about Deep /Shallow copy   
Jul 15, 2007 7:20 PM (reply 2 of 18)  (In reply to original post )

 
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.
 
jverd
Posts:51,815
Registered: 3/30/99
Re: All about Deep /Shallow copy   
Jul 15, 2007 7:27 PM (reply 3 of 18)  (In reply to #2 )

 
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.
 
petes1234
Posts:6,582
Registered: 4/8/07
Re: All about Deep /Shallow copy   
Jul 15, 2007 7:30 PM (reply 4 of 18)  (In reply to #3 )

 
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
 
jverd
Posts:51,815
Registered: 3/30/99
Re: All about Deep /Shallow copy   
Jul 15, 2007 7:34 PM (reply 5 of 18)  (In reply to #4 )

 
Pardon my ignorance, but what are the advantages of
the copy method?

http://www.javapractices.com/Topic71.cjp
 
petes1234
Posts:6,582
Registered: 4/8/07
Re: All about Deep /Shallow copy   
Jul 15, 2007 7:45 PM (reply 6 of 18)  (In reply to #5 )

 
Got it. Thanks. So copy constructor is what is called for in this case since you have a specific object to copy....

again, thanks
 
George123
Posts:273
Registered: 6/25/07
Re: All about Deep /Shallow copy   
Jul 15, 2007 8:13 PM (reply 7 of 18)  (In reply to #6 )

 
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.
 
jverd
Posts:51,815
Registered: 3/30/99
Re: All about Deep /Shallow copy   
Jul 15, 2007 8:31 PM (reply 8 of 18)  (In reply to #7 )

 
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.
 
flounder
Posts:14,625
Registered: 3/2/05
Re: All about Deep /Shallow copy   
Jul 15, 2007 8:34 PM (reply 9 of 18)  (In reply to #8 )

 
this(aGalaxy.getMass(), aGalaxy.getName());

What exactly do you thing the second argument is for? Window dressing perhaps.
 
George123
Posts:273
Registered: 6/25/07
Re: All about Deep /Shallow copy   
Jul 16, 2007 6:17 AM (reply 10 of 18)  (In reply to #9 )

 
Sorry, me bad. My example should have used a class variable other than name, but you get the idea.
 
jbish
Posts:2,412
Registered: 5/3/01
Re: All about Deep /Shallow copy   
Jul 16, 2007 6:39 AM (reply 11 of 18)  (In reply to original post )

 
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).
 
kdgregory
Posts:1,943
Registered: 2/25/00
Re: All about Deep /Shallow copy   
Jul 16, 2007 7:16 AM (reply 12 of 18)  (In reply to #3 )

 
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.
 
jverd
Posts:51,815
Registered: 3/30/99
Re: All about Deep /Shallow copy   
Jul 16, 2007 8:16 AM (reply 13 of 18)  (In reply to #12 )

 
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.
 
BigDaddyLoveHandles
Posts:12,986
Registered: 8/30/04
Re: All about Deep /Shallow copy   
Jul 16, 2007 8:26 AM (reply 14 of 18)  (In reply to #13 )

 
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.)
 
This topic has 18 replies on 2 pages.    1 | 2 | Next »
Back to Forum
 
Read the Developer Forums Code of Conduct

Click to email this message Email this Topic

Edit this Topic
  
 
 
Forums Statistics
    Users Online : 25
  • Guests : 145

About Sun forums
  • Sun Forums is a large collection of user generated discussions. It is here to help you ask questions, find answers, and participate in discussions.

    Check out our guide on Getting started with Sun Forums for a full walkthrough of how to best leverage the benefits of this community.

Powered by Jive Forums