gudii9
asked on
Deep Clone Example
Hi,
I am working on below example
http://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/
i have not understood what author is mentioning as below relating to deep clone.
My code looks as below
I got output as below which is also not clear to me
Jamie Zawinski
Programmer
How is implementign cloneable different from sefializable?
please advise
Any links resources ideas highly appreciated. Thanks in advance
I am working on below example
http://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/
i have not understood what author is mentioning as below relating to deep clone.
Deep Copy
When you need a deep copy then you need to implement it yourself. When the copied object contains some other object its references are copied recursively in deep copy. When you implement deep copy be careful as you might fall for cyclic dependencies. 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.
One more disadvantage with this clone system is that, most of the interface / abstract class writers in java forget to put a public clone method. For example you can take List. So when you want to clone their implementations you have to ignore the abstract type and use actual implementations like ArrayList by name. This completely removes the advantage and goodness of abstractness.
When implementing a singleton pattern, if its superclass implements a public clone() method, to prevent your subclass from using this class’s clone() method to obtain a copy overwrite it and throw an exception of type CloneNotSupportedException.
Note that clone is not for instantiation and initialization. It should not be synonymously used as creating a new object. Because the constructor of the cloned objects may never get invoked in the process. It is about copying the object in discussion and not creating new. It completely depends on the clone implementation. One more disadvantage (what to do there are so many), clone prevents the use of final fields. We have to find roundabout ways to copy the final fields into the copied object.
My code looks as below
class Employeee implements Cloneable {
private String name;
private String designation;
public Employeee() {
this.setDesignation("Programmer");
}
public String getDesignation() {
return designation;
}
public void setDesignation(String designation) {
this.designation = designation;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Object clone() throws CloneNotSupportedException {
/*
* CloneExample2222 copyObj = new CloneExample2222();
* copyObj.setDesignation(this.designation); copyObj.setName(this.name);
* return copyObj;
*/
return super.clone();
}
}
public class CloneExample2222 {
public static void main(String arg[]) {
Employeee jwz = new Employeee();
jwz.setName("Jamie Zawinski");
try {
Employeee joel = (Employeee) jwz.clone();
System.out.println(joel.getName());
System.out.println(joel.getDesignation());
} catch (CloneNotSupportedException cnse) {
System.out.println("Cloneable should be implemented. " + cnse);
}
}
}
I got output as below which is also not clear to me
Jamie Zawinski
Programmer
How is implementign cloneable different from sefializable?
please advise
Any links resources ideas highly appreciated. Thanks in advance
ASKER
deepCopy.toString() returns "Sam, Tony, Lisa" because it contains a different internal list than start does. So when we removed "Sam" it didn't affect deep copy.
How and where do i see to find it contains different internal list. What is the name of internal list deepCopy, shallowCopy has. For me it seems both has same list as below
public MyList createShallowCopy() {Please advise
MyList newList = new MyList(m_Names) ;
}
public MyList createDeepCopy() {
MyList newList = new ArrayList<String>() ;
newList.addAll(this.m_Names) ;
return newList ;
}
Oops - my code has some typos which may have thrown you off.
Should be:
Can you see now how the deep copy is creating a newInternalList while the shallow copy doesn't do that?
Doug
Should be:
public MyList createShallowCopy() {
MyList newList = new MyList(m_Names) ;
return newList ;
}
public MyList createDeepCopy() {
List<String> newInternalList = new ArrayList<String>() ;
newInternalList.addAll(this.m_Names) ;
MyList newList = new MyList(newInternalList) ;
return newList ;
}
Can you see now how the deep copy is creating a newInternalList while the shallow copy doesn't do that?
Doug
ASKER
deepCopy.toString() returns "Sam, Tony, Lisa" because it contains a different internal list than start does. So when we removed "Sam" it didn't affect deep copy.
List<String> newInternalList = new ArrayList<String>() ;
newInternalList.addAll(this.m_Names)
I wonder why newInternalList again contains m_Names similar to Shallow Copy.
I did not get the gist of removing list member etc and how it is different in both cases?
I am still not very clear. Can you please post complete code which i can run and see. Please advise
ASKER
Can you see now how the deep copy is creating a newInternalList while the shallow copy doesn't do that?
I do not understand clearly.
I modified program as below
public class MyList {
private List<String> m_Names ;
public MyList(List<String> names) { m_Names = names ; }
public void remove(String name) { m_Names.remove(name) ; }
public String toString() { return "List=" + m_Names ; }
public MyList createShallowCopy() {
MyList newList = new MyList(m_Names) ;
return newList ;
}
public MyList createDeepCopy() {
List<String> newInternalList = new ArrayList<String>() ;
newInternalList.addAll(this.m_Names) ;
MyList newList = new MyList(newInternalList) ;
return newList ;
}
}
I see compilation errors like
List cannot be resolved to a type at line 2 and following lines where m_names is used. can you please post complete code. please advise
Add this to the top of the file - so it can resolve List:
import java.util.*;
Doug
import java.util.*;
Doug
ASKER
import java.util.ArrayList;
import java.util.List;
public class MyList {
private List<String> m_Names ;
public MyList(List<String> names) { m_Names = names ; }
public void remove(String name) { m_Names.remove(name) ; }
public String toString() { return "List=" + m_Names ; }
public MyList createShallowCopy() {
MyList newList = new MyList(m_Names) ;
return newList ;
}
public MyList createDeepCopy() {
List<String> newInternalList = new ArrayList<String>() ;
newInternalList.addAll(this.m_Names) ;
MyList newList = new MyList(newInternalList) ;
return newList ;
}
}
It fixed the compilation error once i imported list and array list.
But there is no main method or anything like that. How to run. Can you please provide me complete code to understand this example
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
It makes much more sense. I am still trying to digest.
So the link
http://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/
author program is only clone example right which internally uses shallow copy not deep copy.
>>Employee joel = (Employee) jwz.clone();
author in this example using shallow copy(clone) cloned jamie(jwz) into joe1 object right.
so joe1 name , designation also became same as jamie. So output is
Jamie Zawinski
Programmer
Is my understanding is correct?
So the link
http://javapapers.com/core-java/java-clone-shallow-copy-and-deep-copy/
author program is only clone example right which internally uses shallow copy not deep copy.
>>Employee joel = (Employee) jwz.clone();
author in this example using shallow copy(clone) cloned jamie(jwz) into joe1 object right.
so joe1 name , designation also became same as jamie. So output is
Jamie Zawinski
Programmer
Is my understanding is correct?
Yes that's right. Clone() is a built-in method but it only does a shallow copy. If you want a deep copy you need to write it yourself.
(There are lots of problems with clone(). The usual advice is to avoid it because unless you're very careful with it, it will do something different from what you want - like this example of a shallow copy).
Doug
(There are lots of problems with clone(). The usual advice is to avoid it because unless you're very careful with it, it will do something different from what you want - like this example of a shallow copy).
Doug
ASKER
I found below links also helpful
https://www.youtube.com/watch?v=i7_OKhrKoZ4
https://www.youtube.com/watch?v=N52zCY0FqP8
https://www.youtube.com/watch?v=i7_OKhrKoZ4
https://www.youtube.com/watch?v=N52zCY0FqP8
This only matters when the object being copied, contains other objects.
E.g.
Open in new window
Take a look at the differences between createShallowCopy() and createDeepCopy().
Imagine we have:
List<String> names = new ArrayList<String>() ;
names.add("Sam") ;
names.add("Tony") ;
names.add("Lisa") ;
MyList start = new MyList(names) ;
Now if we create a shallow copy:
MyList shallowCopy = start.createShallowCopy() ;
MyList deepCopy = start.createDeepCopy() ;
the list *inside* shallowCopy and start are both the same list.
So if we now do:
start.toString() returns "Sam, Tony, Lisa"
shallowCopy.toString() returns "Sam, Tony, Lisa"
deepCopy.toString() returns "Sam, Tony, Lisa"
start.remove("Sam") ;
start.toString() returns "Tony, Lisa".
But:
shallowCopy.toString() also returns "Tony, Lisa" because the list inside shallowCopy is the same list as the one inside start.
That may be OK, or it may not. But it's different from deep copy:
deepCopy.toString() returns "Sam, Tony, Lisa" because it contains a different internal list than start does. So when we removed "Sam" it didn't affect deep copy.
Does that all make sense?
The rest of the article just talks about specifically what clone does (a shallow copy) and some of the reasons why it's usually best avoided.
Also if you implement serializable you can potentially use that to make a copy since you serialize the data into some form and then deserialize that to get back to the original. If you do that without throwing away the original then it produces a copy. So it's one way to copy an object.
Doug