How Cloning Works ...
· In Java, when you assign an object to another variable, only the memory address of the object is copied and hence any changes in the original object will be reflected in the new variable.
MainObject obj1 = new MainObject(); obj2 = obj1;
· Now cloning comes into picture, when if you don’t want to copy memory address and expecting to copy content values.
So what is cloning?
· Cloning means creating a copy of the object.
This copy of an object can be achieved through the Copy Contractor.
What is copy-constructor?
· A copy constructor is one that takes object of its own type as a single parameter.
EX:
public
class Person {
private Car car;
private String name;
public Person(Car c, String n) {
car = c;
name = n;
}
public Person(Person p)
{
name = p.name;
car = new Car(p.car);
// we assume we have a copy
//constructor for Car
}
public String toString() {
return "This is person has
" + car;
}
}
public
class Car {
public Car() {}
}
|
public
class CopyConstructorMain {
public static void main(String [] args) {
Person person1 = new Person(new
Car(), "Ben");
Person person2 = new Person(person1);
System.out.println(person1);
System.out.println(person2);
}
}
Output is:
----------
This is
person has Car@4edbb0
This is
person has Car@3f75e0
|
·
There is a limitation with the copy constructor,
like if the variable "car" in Person class is actually an instance of
a subclass “Benz” then you will get the wrong answer; what is called a slice.
· To avoid this problem we have cloning concept now.
· To avoid this problem we have cloning concept now.
How do
you implement cloning in java?
·
Implement “Cloneable” interface. (The class registers with the JVM to get
permission for cloning)
·
Override “clone()” method with a try-catch block
for CloneNotSupportedException.
What is Shallow Copy?
- Shallow copy is a bit-wise copy of an object.
- The class variables and associated values will be copied fine.
- But if we have any other class object and respective references, then only reference memory address will be copied for new cloned object.
- When you copy the "ColoredCircle" using clone() method, the fields x and y are copied perfectly with values but field "color" is copied by reference.
- So any changes you make to the color of the original object will be reflected in the copied object and vice versa.
- To avoid that, we have deep copy.
- What is Deep Copy?
- The class variables and associated values will be copied
fine.
- And also references and associated objects will be copied.
- So changes done in both the classes are independent.
- Change the Color class to implement "Cloneable"
interface and clone() method and call the clone() method of color object
inside the clone() method of the ColoredCircle object.
- Look at the changed Color class and ColoredCircle class
below.
Shallow Copy
|
Deep Copy
|
public
class Color {
private String color;
public Color(String c){
this.color = c;
}
//getters and setters for the fields
should go here........
}
public
class ColoredCircle implements Cloneable {
private int centerX;
private int centerY;
private Color color;
public ColoredCircle(int x,
int y, Color c){
this.centerX = x;
this.centerY =
y;
this.color =
c;
}
public Object clone() {
try {
return (ColoredCircle)super.clone();
}
catch
(CloneNotSupportedException e) {
// This
should never happen
}
}
//getters and setters for the fields
should go here........
}
public
class CloneMain {
public static void main(String [] args) {
Color c =
new Color("RED");
ColoredCircle
c1 = new ColoredCircle(200,200,c);
ColoredCircle c2 = c1.clone();
}
}
|
public
class Color implements Cloneable{
private String color;
public Color(String c){
this.color = c;
}
public Object clone() {
try {
return (Color)super.clone();
}
catch
(CloneNotSupportedException e) {
// This
should never happen
}
}
//getters and setters for the fields
should go here........
}
public
class ColoredCircle implements
Cloneable {
private int centerX;
private int centerY;
private Color color;
public ColoredCircle(int x, int y, Color
c){
this.centerX = x;
this.centerY = y;
this.color = c;
}
public Object clone() {
ColoredCircle
coloredCircle = null;
try {
coloredCircle =
(ColoredCircle)super.clone();
}
catch
(CloneNotSupportedException e) {
// This
should never happen
}
coloredCircle.color
= (Color) color.clone();
return coloredCircle;
}
//getters and setters for the fields
should go here........
}
|
- Deep copy can be achieved through serialization, but only
limitation is Transient variables will not be copied properly.
Question:
if clone is a protected method then why the sub class has to implement
Cloneable interface type to use its super class method?
Answer:
clone is a dangerous method. So by implementing Cloneable interface you are
telling JVM that "There is a good reason to clone my class, so please
allow me".
Note:
·
While making use of Object clone() method, it
will just returns Object type, so this is our responsibility to Type cast to
Our class type.
When to do shallow copy and deep copy?
When to do shallow copy and deep copy?
·
It’s
very simple that if the object has only primitive fields, then obviously you
will go for shallow copy.
· But if the object has references to other objects, then based on the requirement, shallow copy or deep copy should be chosen.
· What I mean here is, if the references are not modified anytime, and then there is no point in going for deep copy. You can just opt shallow copy.
· But if the object has references to other objects, then based on the requirement, shallow copy or deep copy should be chosen.
· What I mean here is, if the references are not modified anytime, and then there is no point in going for deep copy. You can just opt shallow copy.
·
But if
the references are modified often, then you need to go for deep copy. Again
there is no hard and fast rule; it all depends on the requirement.
Lazy
copy:
·
A lazy copy is a combination of both shallow
copy and deep copy.
· When initially copying an object, a (fast) shallow copy is used.
· When the program wants to modify the original object, it can determine if the data is shared (by examining the counter) and can do a deep copy at that time if necessary.
· When initially copying an object, a (fast) shallow copy is used.
· When the program wants to modify the original object, it can determine if the data is shared (by examining the counter) and can do a deep copy at that time if necessary.
· Lazy
copy looks to the outside just as a deep copy but takes advantage of the speed
of a shallow copy whenever possible.
No comments :
Post a Comment