Copy Constructors in Java

Hi all,

We have a new topic over here to learn – The Copy Constructors.

WHAT ?

A copy constructor is a constructor that takes only one argument which is of the type as the class in which the copy constructor is implemented. For example, let us assume a class namely Car and it has a constructor called copy constructor which expects only one argument of type Car.

WHY ?

Copy constructors are widely used for creating a duplicates of objects known as cloned objects. Duplicate object in the sense the object will have the same characteristics of the original object from which duplicate object is created. But we have to ensure that both original and duplicate objects refer to different memory locations.

WHERE ?

It’s our responsibility to implement a copy constructor in our class in the right way. As mentioned above, it’s used to duplicate objects. So we are free to use copy constructors instead of clone method in java.

HOW ?

Copy constructors are implemented for deep cloning and shallow cloning. Both these cloning techniques can be achieved by overriding the clone method in java. Shallow cloning is the default cloning implementation in java and we just need to override the clone method. But deep cloning has to be implemented as per our need and logic. Explaining about cloning is beyond the scope of this post. So let’s come back.

When you pass an instance of a particular class to copy constructor, it returns a new instance of the same class with all values copied from the parameter instance. Let’s see to an example.

Department.java


public class Department {

    private String name;
    private int id;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Department(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public Department(Department oldDepartment) {
        this.id = oldDepartment.id;
        this.name = oldDepartment.name;
    }

    @Override
    public String toString() {
        return "Department Id: " + id + "\tDepartment Name: " + name;
    }
}

Employee.java


public class Employee {

    private String name;
    private int id;
    private Department department;

    public Department getDepartment() {
        return department;
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(int id, String name, Department department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    public Employee(Employee oldEmployee) {
        this.id = oldEmployee.id;
        this.name = oldEmployee.name;
        this.department = oldEmployee.department;  //shallow cloning
    }

    @Override
    public String toString() {
        return "Employee Id: " + id + "\tEmployee Name: " + name + "\t" + department;
    }
}

Okay, it’s the time to test. Let’s do that.

CopyConstructors.java


public class CopyConstructorTest {

   public static void main(String[] args) {
        Department department = new Department(1, "Finance");
        Employee originalEmployee = new Employee(1, "Ram", department);
        Employee clonedEmployee = new Employee(originalEmployee);
        System.out.println("Original:- " + originalEmployee);
        System.out.println("Duplicate:- " + clonedEmployee);
        System.out.println();
        clonedEmployee.setId(2);
        clonedEmployee.setName("Laxman");
        clonedEmployee.getDepartment().setName("HR");
        System.out.println("Original:- " + originalEmployee);
        System.out.println("Duplicate:- " + clonedEmployee);
    }
}

The Output

Original:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance
Duplicate:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance

Original:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: HR
Duplicate:- Employee Id: 2	Employee Name: Laxman	Department Id: 1	Department Name: HR

What have we done above? We have two classes namely Department and Employee and created their copy constructors in the respective classes. The Department class has only two variables namely id and name. In the Employee class, there are two variables and an instance of Department class.

Then we create an object of Employee class namely originalEmployee in the main method and create a duplicate object namely clonedEmployee of the originalEmployee object.

But what happens in the above example is, when we change the department name of clonedEmployee, the change comes up with the originalEmployee also (just look over the output, the department name of originalEmployee object changed from Finance to HR). Why it behaves so because what we implement here is shallow cloning (see the highlighted line). It means the department member of both originalEmployee and clonedEmployee refers to the same memory location. When our implementation is changed from shallow cloning to deep cloning, the following things happen.

Let’s have a small change in the copy constructor of Employee class (look over the following highlighted line).

Employee.java


public class Employee {

    private String name;
    private int id;
    private Department department;

    public Department getDepartment() {
        return department;
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(int id, String name, Department department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    public Employee(Employee oldEmployee) {
        this.id = oldEmployee.id;
        this.name = oldEmployee.name;
        this.department = new Department(oldEmployee.department);    //deep cloning
    }

    @Override
    public String toString() {
        return "Employee Id: " + id + "\tEmployee Name: " + name + "\t" + department;
    }
}

Now we test again and the output is

Original:-  Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance
Duplicate:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance

Original:-  Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance
Duplicate:- Employee Id: 2	Employee Name: Laxman	Department Id: 1	Department Name: HR

Now everything goes fine and this is what we call deep cloning using copy constructors.

SUBSTITUTE ?

In certain situations we can’t make our copy constructor public, so it has to be private. Now we need to think about an equivalent and yes, fortunately we are able to find out another workaround for achieving the same result- The Factory Method. Let’s have a look.

Employee.java


public class Employee {

    private String name;
    private int id;
    private Department department;

    public Department getDepartment() {
        return department;
    }

    public String getName() {
        return name;
    }

    public int getId() {
        return id;
    }

    public void setDepartment(Department department) {
        this.department = department;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public Employee(int id, String name, Department department) {
        this.id = id;
        this.name = name;
        this.department = department;
    }

    private Employee(Employee oldEmployee) {
        this.id = oldEmployee.id;
        this.name = oldEmployee.name;
        this.department = new Department(oldEmployee.department);    //deep cloning
    }

    @Override
    public String toString() {
        return "Employee Id: " + id + "\tEmployee Name: " + name + "\t" + department;
    }

    public static Employee copy(Employee originalEmployee) {
        return new Employee(originalEmployee);
    }
}

Now we can make our copy constructor private (making it so is a good achievement) and our factory method in turn calls the constructor. It also gives us the same output. Let’s test it right away.

CopyConstructorTest.java


public class CopyConstructorTest {

    public static void main(String[] args) {
        Department department = new Department(1, "Finance");
        Employee originalEmployee = new Employee(1, "Ram", department);
        Employee clonedEmployee = Employee.copy(originalEmployee);
        System.out.println("Original:- " + originalEmployee);
        System.out.println("Duplicate:- " + clonedEmployee);
        System.out.println();
        clonedEmployee.setId(2);
        clonedEmployee.setName("Laxman");
        clonedEmployee.getDepartment().setName("HR");
        System.out.println("Original:- " + originalEmployee);
        System.out.println("Duplicate:- " + clonedEmployee);
    }
}

The Output


Original:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance
Duplicate:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance

Original:- Employee Id: 1	Employee Name: Ram	Department Id: 1	Department Name: Finance
Duplicate:- Employee Id: 2	Employee Name: Laxman	Department Id: 1	Department Name: HR

Thanks.

Advertisements

16 Comments

  1. Bujji

    NICE

  2. Ali

    Nice ❀

  3. good one Thanks dear πŸ™‚

    • Rafiqul

      thanks

  4. Nida

    Great,very helpful
    Thank you so much πŸ™‚

  5. viveksarabu

    very good explanation, i have a small doubt. Thank for advance.
    For deep cloning which one is better,serialization or copy constructor ???????

  6. sankeerthana

    Thank u so much..it is really understandable…

  7. Prosunjit Biswas

    Reblogged this on One Ordinary Blog.

  8. Roopa

    Thanks for the wonderful explanation.
    I have couple of questions though on copy constructors:-
    1. I believed that constructors has to be always public so a copy constructor should also follow the same rule which is not the case here can you explain why.
    2. why is factory method Static.

  9. Awesome, very well written article. Many important points are covered here.Its really a great and useful piece of information. Im glad that you shared this helpful information with us.
    Please stay us up to date like this. Thanks for sharing.

  10. Real informative and excellent anatomical structure of content material, now that’s user pleasant (:.

Trackbacks

  1. Why do we need copy constructor and when should we use copy constructor in java | Solutions for enthusiast and professional programmers
  2. Everything about Cloning Java « CodeThatAint Blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: