Java Copy Constructor – Advantages and Examples

Welcome back to Techvidvan Java Tutorial Series.

Sometimes, a developer falls into a situation where he needs to create a duplicate but exact copy of an existing object of a class. He wants to create a separate copy but the exact one of the existing objects such that the changes made in the duplicate copy won’t reflect on the original object or vice-versa.

Java makes this possible by providing a concept of Copy Constructors. Java copy constructors are the special type of Constructors in Java that we use to create a duplicate of the existing object of a class. In this article, we will learn how to create and use a java copy constructor with examples.

What is a Java Copy Constructor?

A Copy Constructor in Java is a special type of constructor that is used to create a new object using the existing object of a class that we have created previously. It creates a new object by initializing the object with the instance of the same class.

The Java Copy Constructor provides a copy of the specified object by taking the argument as the existing object of the same class. Java does not implicitly provide the facility of a Copy constructor as in C language. But, we can define it by copying the values of one object to another object.

copy constructor in java

Creating a Copy Constructor in Java

To create a copy constructor in Java, we need to first declare a constructor that takes an object of the same type as a parameter. For example:

public class Student
{
        private int roll ;
        private String name;

        // Declaring a copy constructor by passing the parameter as the class
        public Student( Student student )
        {
        }
}

After declaring a copy constructor, we need to copy each field of the input object of the class into the new object. For example:

public class Student
{
        private int roll;
        private String name;

        // Copying each field of the existing object into the newly created object
        public Student( Student student )
        {
                this.id = student.roll;
                this.name = student.name;
        }
}

From the above code snippet, we created a shallow copy of the object. It will work fine as we are using the immutable and primitive types, i.e int and String.

But what if we have mutable types in our code?

If there is a mutable data type in Java program, then we can create a deep copy rather than a shallow copy so that the newly created object becomes independent of the existing object. Let’s see an example:

public class Student
{
        private int roll;
        private String name;
        private Date admissionDate;

        public Student( Student student )
        {
                this.roll = student.id;
                this.name = student.name;
                this.admissionDate = new Date(student.admissionDate.getTime());
        }
}

Example of Copy Constructor in Java

package com.techvidvan.copyconstructor;
public class Student 
{
  private int roll;
  private String name;

  //constructor to initialize roll number and name of the student
  Student(int rollNo, String sName)
  { 
    roll = rollNo;
    name = sName;
  }

  //copy constructor
  Student(Student student)
  {
    System.out.println("\n---Copy Constructor Invoked---");
    roll = student.roll;
    name = student.name;
  }
  //method to return roll number
  int printRoll()
  {
    return roll;
  }
//Method to return name of the student
  String printName()
  {
    return name;
  }
  //class to create student object and print roll number and name of the student

  public static void main(String[] args)
  {
    Student student1 = new Student(101, "Sneha");
    System.out.println("Roll number of the first student: "+ student1.printRoll());
    System.out.println("Name of the first student: "+ student1.printName());

    //passing the parameter to the copy constructor
    Student student2 = new Student(student1);

    System.out.println("\nRoll number of the second student: "+ student2.printRoll());
    System.out.println("Name of the second student: "+ student2.printName());
  }
}

Output:

Roll number of the first student: 101
Name of the first student: Sneha
—Copy Constructor Invoked—
Roll number of the second student: 101
Name of the second student: Sneha

Advantages of Copy Constructor in Java

The Copy constructor in java has several advantages that encourage every Java developer to use it in the Java code. Let’s discuss these advantages of Copy constructor in Java:

  1. The Copy constructor is easier to use when our class contains a complex object with several parameters.
  2. Whenever we want to add any field to our class, then we can do so just by changing the input to the constructor.
  3. One of the most crucial importance of copy constructors is that there is no need for any typecasting.
  4. Copy Constructors allow us to change the fields declared as final.
  5. Using a copy constructor, we can have complete control over object creation.

Creating Duplicate objects without using a Copy Constructor

We can also create a copy of an object without using a copy constructor, just by assigning the values of one object into the other object. See the below example to understand this:

Code to create a copy of an object without using a copy constructor

package com.techvidvan.copyconstructor;
public class Student 
{
  private int roll;
  private String name;

  //constructor to initialize roll number and name of the student
  Student(int rollNo, String sName)
  { 
    roll = rollNo;
    name= sName;
  }
  
  Student()
  {	
  }

  //method to return roll number
  int printRoll()
  {
    return roll;
  }
  //Method to print name
  String printName()
  {
    return name;
  }
  //class to create student object and print roll number and name of the student

  public static void main(String[ ] args)
  {
    Student student1 = new Student(101, "Sneha");
    System.out.println("Roll number of the first student: "+ student1.printRoll());
    System.out.println("Name of the first student: "+ student1.printName());

    Student student2 = new Student();
    student2.roll= student1.roll;
    student2.name= student1.name;

    System.out.println("\nRoll number of the second student: "+ student2.printRoll());
    System.out.println("Name of the second student: "+ student2.printName());
  }
}

Output:

Roll number of the first student: 101
Name of the first student: Sneha
Roll number of the second student: 101
Name of the second student: Sneha

Java Copy Constructor vs. clone() method in Java

We can also use the clone() method to get a copy of an object from an existing object of the class. But the Copy constructor is better to use than the clone() method because of the following reasons:

1. It is easier to implement and use a copy constructor than the clone() method. Because when using the clone() method to create an object, we need to implement the Cloneable interface in our program and also need to handle the CloneNotSupportedException. In the Copy constructor, there is no need for such complex things in our program.

2. We need to typecast the object returned by the clone() method to the appropriate type. There is no need of typecasting the objects while using the copy constructor.

3. When we use a clone() method, we can not assign a value to a final field. But, we can do so in the copy constructor.

Inheritance Issues

The subclasses or the child classes can not extend the Copy constructors in Java. If we try to initialize a child object from a parent class reference, we will get a casting error.

To understand this issue, let’s first create a subclass of Student and its copy constructor:

public class EngineeringStudent extends Student
{
private List<Student> performanceReport;
    	// ... other constructors
 
    	public EngineeringStudent(EngineeringStudent engineeringStudent)
{
        		super(enggStudent.roll, enggStudent.name, enggStudent.admissionDate);
        		this.performanceReport = performanceReport.stream().collect(Collectors.toList());
   	}
}

Then, we declare a Student variable and instantiate it with the constructor of the EngineeringStudent class:

Student student = new EngineeringStudent(101, “Shreya”, admissionDate, performanceReports);

Since the reference type is of Student class, we need to typecast it to the EngineeringStudent type so that we can use the copy constructor of the Student class:

Student clone = new EngineeringStudent((EngineeringStudent) student);

We may get a ClassCastException at runtime if the input object is not of the EngineeringStudent class type. One way to avoid casting in the copy constructor is to create a new inheritable method for both classes. For example:

public class Student
{
public Student copy()
{
        		return new Student(this);
    	}
}
 
public class EngineeringStudent extends Student
{
@Override
    	public Student copy() 
{
        		return new EngineeringStudent(this);
    	}
}

Conclusion

Java copy constructor is used to create a copy of the current object of the class. We can create a copy constructor explicitly by passing it an argument as the class name whose object we want to create.

In this tutorial, we studied what a copy constructor in Java is and how can we create it in Java. We also discussed some issues regarding the copy constructor in java and how we can recover from those issues.

Everything in this article was explained with example. This article will assure you that you strengthen your concepts in Java Copy Constructor.

Do share your feedback in the comment section.