In this post, we will see about copy constructor in java.
Copy constructor
is the constructor which takes parameter as object of same class and copy each field of the class to the new object. Unlike C++, java does not provide default copy contructor. You need to create one, if you want to have copy constructor in your class.Copy constructor is alternate to clone
method.
Let’s say you have class name Country, so copy constructor will look like below:
1 2 3 4 5 6 |
public Country(Country countryObj) { // Manually copying each field of country class } |
Java Copy Contructor
Copy constructors are used to create duplicate objects or cloned objects.Newly created object will have same characteristics as the original object. We need to be very careful while using Copy constructor because it is the responsibility of programmer to ensure that newly created object refers to different memory location than original. If you are confused here, don’t worry, I will explain you this with the help of an example.
Let’s understand use of Copy constructor
with the help of simple example.
Create a class name capital.java as below:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
package org.arpit.java2blog; public class Capital { String capitalName; long population; public Capital(String name, long population) { super(); this.capitalName = name; this.population = population; } public String getCapitalName() { return capitalName; } public void setCapitalName(String name) { this.capitalName = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } } |
Create another class as Country.java. Please note that Country has a reference to above capital class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package org.arpit.java2blog; public class Country { String name; long population; Capital capital; public Country(String name, long population,Capital capital) { super(); this.name = name; this.population = population; this.capital=capital; } // Copy constructor public Country(Country c) { super(); this.name = c.name; this.population = c.population; this.capital=c.capital; // Shallow copy } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } public Capital getCapital() { return capital; } public void setCapital(Capital capital) { this.capital = capital; } } |
Let’s create main class named "CopyConstructorMain.java"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
package org.arpit.java2blog; public class CopyConstructorMain { public static void main(String[] args) { // Create capital object Capital capital=new Capital("Delhi", 10000); // Create country object Country countryIndia=new Country("India", 90000,capital); // Use copy constructor to create duplicate object Country countryIndiaCopied=new Country(countryIndia); System.out.println("Country name of Copied object: "+countryIndiaCopied.getName()); System.out.println("Country population of Copied object: "+countryIndiaCopied.getPopulation()); System.out.println("Capital name of Copied object: "+countryIndiaCopied.getCapital().getCapitalName()); System.out.println("Capital population of Copied object: "+countryIndiaCopied.getCapital().getPopulation()); System.out.println("============================================"); // Changing capital name of original object countryIndia.getCapital().setCapitalName("Mumbai"); System.out.println("Capital name of Original object: "+countryIndia.getCapital().getCapitalName()); System.out.println("Capital name of Copied object: "+countryIndiaCopied.getCapital().getCapitalName()); } } |
When you run above program, you will get below output:
Country population of Copied object: 90000
Capital name of Copied object: Delhi
Capital population of Copied object: 10000
============================================
Capital name of Original object: Mumbai
Capital name of Copied object: Mumbai
We are able to copy all content of countryIndia to countryIndiaCopied. That’s great!!
But did you notice an issue here? When we changed capital name in original object, it got changed in duplicate object too.This is because we have done shallow copy in case of capital object, so both objects are referring to same capital reference.You need to be careful while using copy constructor as it may result in unexpected behavior and it is very hard to debug.
Let’s create a deep copy in copy constructor of the Country class and it should fix above issue.
Introduce a copy constructor in Capital class and use it in copy constructor of the Country class.
Capital.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package org.arpit.java2blog; public class Capital { String capitalName; long population; public Capital(String name, long population) { super(); this.capitalName = name; this.population = population; } // Copy constructor public Capital(Capital oldCapital) { this.capitalName = oldCapital.capitalName; this.population = oldCapital.population; } public String getCapitalName() { return capitalName; } public void setCapitalName(String name) { this.capitalName = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } } |
Country.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
package org.arpit.java2blog; public class Country { String name; long population; Capital capital; public Country(String name, long population,Capital capital) { super(); this.name = name; this.population = population; this.capital=capital; } // Copy constructor public Country(Country c) { super(); this.name = c.name; this.population = c.population; this.capital=new Capital(c.capital); // Deep copy } public String getName() { return name; } public void setName(String name) { this.name = name; } public long getPopulation() { return population; } public void setPopulation(long population) { this.population = population; } public Capital getCapital() { return capital; } public void setCapital(Capital capital) { this.capital = capital; } } |
Now you execute CopyConstructorMain.java, you will get below output:
Country population of Copied object: 90000
Capital name of Copied object: Delhi
Capital population of Copied object: 10000
============================================
Capital name of Original object: Mumbai
Capital name of Copied object: Delhi
As you can see here, when we made changes to capital
name of original object, it did not impact copied object.
If you have mutable object in the class then you need to take care of it by doing deep copy while creating duplicates.Otherwise, it may result in unexpected behaviour.
that’s all about copy constructor in java.