Copying an object in java means creating a new object of same type and copying each of the attributes of your object to this newly created object.
When your class has only primitive types as its attributes then copy is shallow or deep it does not matter. But when your class contains objects of another classes as one of its members then it makes difference.
Lets see how an object can be copied using shallow copy method.
Following code has two classes - Engine and Car. Car class contains Engine object as one of its members. Car class has a static method createShallowCopy() which will be used to create a copy of Car object passed to it.
Make=Maruti
****Engine Details****
Engine Location=Front
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
The above program creates a Car instance , then creates its copy using createShallowCopy() nethod and prints both cars details.
Now while creating a copy of Car object you are copying each attribute of car object (passed as argument to createShallowCopy() method) to the newly created car instance.
Note the statement:
In the above statement you are copying a reference variable instead of a primitive type variable.
Here instead of copying each attribute of engine (of anotherCar) to the attributes of engine( of car), you are just copying a reference variable.
As a result both reference variables engine(of car) and engine(of anotherCar) contains same value and now points to same Engine object. Thus now both cars shares same engine ( an unrealistic situation though ! :-) ). If you change the engine in one car it will be reflected in other car.
Due to this our Car objects - car1 and car2 are not independent.
Now suppose we want to change the location of engine in one of our car object from "front" to "back" as:
Car 1 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
*******************After Change*******************************
Car 1 Details:
Make=Maruti
****Engine Details****
Engine Location=Back
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Back
Note the output. Engine location of both car1 and car2 got changed to Back.
You have changed the location of engine of car2 but both engines ( of car1 and car2) got changed. This is because engine in both objects are pointing to same Engine object.
When your class has only primitive types as its attributes then copy is shallow or deep it does not matter. But when your class contains objects of another classes as one of its members then it makes difference.
Lets see how an object can be copied using shallow copy method.
Following code has two classes - Engine and Car. Car class contains Engine object as one of its members. Car class has a static method createShallowCopy() which will be used to create a copy of Car object passed to it.
class Engine {
private String engineLocation;
Engine(){
}
Engine(String engineLocation){
this.engineLocation=engineLocation;
}
public void setEngineLocation(String engineLocation){
this.engineLocation=engineLocation;
}
public String getEngineLocation(){
return engineLocation;
}
}
public class Car {
private String make;
private Engine engine; /*Reference to Engine Object*/
Car(){
}
Car(String make,Engine engine){
this.make=make;
this.engine=engine;
}
/*Creating a copy of Car object*/
public static Car createShallowCopy(Car anotherCar){
Car car =new Car();
car.make=anotherCar.make;
/*Shallow Copy: Copying a reference variable only, not the attributes of Engine Object */
car.engine=anotherCar.engine;
return car;
}
public void setMake(String make){
this.make=make;
}
public String getMake(){
return make;
}
public void setEngine(Engine engine){
this.engine=engine;
}
public Engine getEngine(){
return engine;
}
public static void main(String args[]){
Engine engine= new Engine("Front");
Car car1 = new Car("Maruti",engine);
/*Creating shallow copy*/
Car car2= Car.createShallowCopy(car1);
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
}
}
private String engineLocation;
Engine(){
}
Engine(String engineLocation){
this.engineLocation=engineLocation;
}
public void setEngineLocation(String engineLocation){
this.engineLocation=engineLocation;
}
public String getEngineLocation(){
return engineLocation;
}
}
public class Car {
private String make;
private Engine engine; /*Reference to Engine Object*/
Car(){
}
Car(String make,Engine engine){
this.make=make;
this.engine=engine;
}
/*Creating a copy of Car object*/
public static Car createShallowCopy(Car anotherCar){
Car car =new Car();
car.make=anotherCar.make;
/*Shallow Copy: Copying a reference variable only, not the attributes of Engine Object */
car.engine=anotherCar.engine;
return car;
}
public void setMake(String make){
this.make=make;
}
public String getMake(){
return make;
}
public void setEngine(Engine engine){
this.engine=engine;
}
public Engine getEngine(){
return engine;
}
public static void main(String args[]){
Engine engine= new Engine("Front");
Car car1 = new Car("Maruti",engine);
/*Creating shallow copy*/
Car car2= Car.createShallowCopy(car1);
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
}
}
Output:
Car 1 Details:Make=Maruti
****Engine Details****
Engine Location=Front
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
The above program creates a Car instance , then creates its copy using createShallowCopy() nethod and prints both cars details.
Now while creating a copy of Car object you are copying each attribute of car object (passed as argument to createShallowCopy() method) to the newly created car instance.
Note the statement:
car.engine = anotherCar.engine;
In the above statement you are copying a reference variable instead of a primitive type variable.
Here instead of copying each attribute of engine (of anotherCar) to the attributes of engine( of car), you are just copying a reference variable.
As a result both reference variables engine(of car) and engine(of anotherCar) contains same value and now points to same Engine object. Thus now both cars shares same engine ( an unrealistic situation though ! :-) ). If you change the engine in one car it will be reflected in other car.
Due to this our Car objects - car1 and car2 are not independent.
This is shallow copy. In Shallow copy you do not copy each attribute of the component classes but only copy their reference variables.
Side Effect of Shallow Copy
Now suppose we want to change the location of engine in one of our car object from "front" to "back" as:
main() (changed):
public static void main(String args[]){
Engine engine= new Engine("Front");
Car car1 = new Car("Maruti",engine);
/*Creating shallow copy*/
Car car2= Car.createShallowCopy(car1);
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
/*Changing Engine Location of car2*/
car2.getEngine().setEngineLocation("Back");
System.out.println("*******************After Change****************************");
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
}
Engine engine= new Engine("Front");
Car car1 = new Car("Maruti",engine);
/*Creating shallow copy*/
Car car2= Car.createShallowCopy(car1);
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
/*Changing Engine Location of car2*/
car2.getEngine().setEngineLocation("Back");
System.out.println("*******************After Change****************************");
System.out.println("Car 1 Details:");
System.out.println("Make="+car1.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car1.getEngine().getEngineLocation());
System.out.println("Car 2 Details:");
System.out.println("Make="+car2.getMake());
System.out.println("****Engine Details****");
System.out.println(" Engine Location="+car2.getEngine().getEngineLocation());
}
Output:
Car 1 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Front
*******************After Change*******************************
Car 1 Details:
Make=Maruti
****Engine Details****
Engine Location=Back
Car 2 Details:
Make=Maruti
****Engine Details****
Engine Location=Back
Note the output. Engine location of both car1 and car2 got changed to Back.
You have changed the location of engine of car2 but both engines ( of car1 and car2) got changed. This is because engine in both objects are pointing to same Engine object.
I would like to know your comments and if you liked the article then please share it on social networking buttons.
You may like to read:
How to write a Copy Constructor using Deep copy.
How to write a Copy Constructor using Copy Constructor.
Copying Object by deep copy.
Copying Object by Copy Constructors.
nice explanation.........
ReplyDeleteSimple and clean .Thanks for the explantion
ReplyDelete