Link to home
Start Free TrialLog in
Avatar of gudii9
gudii9Flag for United States of America

asked on

shallow and deep copy

Hi,

I tried below example.

http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

When i run the example I  see  output as below


Before cloning
ce:num:3, thing:Fred

After cloning, setting ce num to 5
After cloning, setting ce thing name to Barney
ce:num:5, thing:Barney
ceShallowClone:num:3, thing:Barney
cdDeepClone:num:3, thing:Fred

Notice that changing ce thing name to Barney changed ceShallowClone's thing name to Barney.
This is because the copy was shallow, and ce's thing and ceShallowClone's thing point to the same Thing.
Notice that ceDeepClone's thing name is Fred. This is because the deep copy resulted in ceDeepClone having its own Thing.



I have not clearly understood the output and difference between shallow and deep copy.


please advise
Any links resources ideas highly appreciated. Thanks in advance
Avatar of Ken Butters
Ken Butters
Flag of United States of America image

In your example class "CloneExample"...

you have two members.

      int num;
      Thing thing;

of those two... one is a primitive (num).
and one is another class (thing).

a shallow copy means that only primitive items will be copied.  in this caes... num would be copied not thing,

For a deep copy, they are simply saying that the class "Thing" needs to take care of copying its own member variables.
Avatar of Mahesh Bhutkar
Mahesh Bhutkar

In Java Object Cloning Shallow copy & Deep Copy concepts come in picture.

A shallow copy of Object contain only primitive data types whereas in case of deep copy reference of another object/class also taken care by serialization concept.
Avatar of gudii9

ASKER

CloneExample ceShallowClone = ce.clone();
            CloneExample cdDeepClone = ce.deepClone();


above lines are not clear to me.
Why they defined below line separately
CloneExample ce = new CloneExample();

Also what is meaning of below line
Notice that changing ce thing name to Barney changed ceShallowClone's thing name to Barney


in case of deep copy reference of another object/class also taken care by serialization concept.

How to take care deep cloning using serialization.


what are practical uses of deep and shallow cloning. which is one is preferred in which case
By your question, I think you are having difficulty understanding the most basic building block of java.  That is the java class.

A java class constitutes members, and methods that can be performed on those methods.

Classes can be embedded and made to be part of other classes.

In the code you are reviewing, CloneExample.java defines an class.  

Review this to gain a better understanding of what class members are.
http://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html

The CloneExample Class contains two members.  
"num" which is an int.  An int is an example of a primitive type.
"thing" which is defined as a "Thing".  Thing is itself defined in a separate class called Thing.java.


The CloneExample class also defines methods that you can perform.  

Review this link to gain a better understanding of what class methods are.
http://docs.oracle.com/javase/tutorial/java/javaOO/methods.html

The methods of a class usually have something to do with manipulating the members of the class in some way.  So I would expect that the members of CloneExample would be used in some way in any methods defined in the CloneExample Class.

There are two main methods defined in the CloneExample class.
clone
DeepClone

to determine what they do... you just need to closely examine the ConeExample class.

the first method "clone" does a shallow clone.  The only thing it does is invoke the super.clone which is to say it simply does a shallow copy.  Again... shallow copy only copies primitives.  in this case the only primitive is the "num" which is an int.

The second method deepClone copies both the int num and the object "thing" to a completely new and separate object.
 

in the main routine when you execute this line of code:
CloneExample ceShallowClone = ce.clone();

you now have two objects.... one is called "ceShallowClone" and one is called "ce".  they each have a num... but since it was a shallow copy.... they both reference the same object called thing.

I am attaching a screenshot trying to show what memory looks like after the shallow copy.

Remember when looking at the picture you have two instances of an object or class. that Class is called CloneExample.   "ce" is one instance of a CloneExample, and ceShallowClone is another instance of CloneExample.   "Thing" is a separate class that is a member of the CloneExample class, so every instance of CloneExample, contains a "Thing" member.

"Thing class in turn has a member variable that is a name of type String.

If you look a the picture, you can see that if you change the name of  the Thing inside ceShallowClone, it will also be changed for ce, because ce and ceShallowClone both point to the same "Thing" object.
2-7-2014-10-39-18-PM.jpg
SOLUTION
Avatar of Mahesh Bhutkar
Mahesh Bhutkar

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of gudii9

ASKER

For a deep copy, they are simply saying that the class "Thing" needs to take care of copying its own member variables.

The second method deepClone copies both the int num and the object "thing" to a completely new and separate object.

deepClone() method is not clear to me as below. What is the need of ByteArrayOutputStream , ByteArrayInputStream , ObjectOutputStream , ObjectInputStream ,writeObject(), readObject(), Serialization etc to copy object as well. Please advise

public CloneExample deepClone() {
		try {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			ObjectOutputStream oos = new ObjectOutputStream(baos);
			oos.writeObject(this);

			ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
			ObjectInputStream ois = new ObjectInputStream(bais);
			return (CloneExample) ois.readObject();

Open in new window


I am attaching a screenshot trying to show what memory looks like after the shallow copy.

Notice that ceDeepClone's thing name is Fred. This is because the deep copy resulted in ceDeepClone having its own Thing.

where ceDeepClone has Fred as its own thing? Which class and which line?
Can you please attach picture after deep copy as well similar to shallow copy attached.
deepClone() method is not clear to me as below. What is the need of ByteArrayOutputStream , ByteArrayInputStream , ObjectOutputStream , ObjectInputStream ,writeObject(), readObject(), Serialization etc to copy object as well. Please advise

All of these methods are NOT necessary to do a deep clone.  You need to refer to the title of the original article you referred to in your original question to get the answer to that.

If you look at your original link:
http://www.avajava.com/tutorials/lessons/how-do-i-perform-a-deep-clone-using-serializable.html

The question being answered at that link is : How do I perform a deep clone using Serializable?

The code that follows that question is how to do a deep clone using serializable.

Normally, the result of serializing an object would be a new file that would be created that has a filetype of ".ser".

In this case, the author did not create an '.ser' file, but instead created a byte array to hold the same data that would normally have been written to an ".ser" file so that you could see how the cloning worked.

So when you do the "oos.writeObject(this)", the byteArray is stored in "baos" or the byteArrayOutputStream...

Now when you want to deserialize (or create an object from the data previously saved) the "baos" is read back in... to deserialize... which means to create a java object from previously saved values.


Serialization / DeSerialization is performed via the "ObjectOutputStream" and "ObjectInputStream" and that is why these classes were used in this example.

The reading and writing to the ByteArray Input/Output streams is done by using the ByteArrayOutputStream and the ByteArrayInputStream. this was used a a place to hold the data that comprises the java objects.  (this is all of the data needed to create the original objects).

There are many many classes in java, and in order to be able to successfully navigate through what they do, you should familiarize yourself with java docs.

Here is the relevant documentation for the classes that are used in your example: (For java SE 7)

http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayOutputStream.html
http://docs.oracle.com/javase/7/docs/api/java/io/ByteArrayInputStream.html

http://docs.oracle.com/javase/7/docs/api/java/io/ObjectOutputStream.html
http://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html


You also asked about writeObject and ReadObject.  These are the methods for the ObjectOutputStream and the ObjectInputStream respectively.  You can review the details of what writeObject and ReadObject methods do by reviewing the appropriate classes at the links provided above.

If you are learning java, I cannot stress enough how important it is to be able to read and understand what is available in javadocs.

they will tell you everything you need to know about a class.  They will give you information on how the constructors work, and information about every single method available for any given class.
Avatar of gudii9

ASKER

Normally, the result of serializing an object would be a new file that would be created that has a filetype of ".ser".


Is there is a simple example with new file type as '.ser' instead of array approach. Please advise
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial