Java

Copy Constructor in Java

Java copy constructor enables us to generate an exact clone of an existing object which belongs to the same class without the new copy being affected by changes made to the original object. By utilizing the copy constructor, the reusability of the code is improved. Its size is reduced, and typecasting is not required. We can fully control the object creation using a copy constructor. Additionally, the Java compiler does not create any copy constructors in a class by default. However, we can establish it by assigning the object content to another one.

Example 1:

Before proceeding with the copy constructor demonstration, we have the working of the default constructor in Java. The default constructors are those constructors which take no parameters. Let’s have the default constructor program in the following:

public class DefaultConst
{
DefaultConst()
    {
System.out.println("Constructor called because Object is Created");
    }    
    public static void main(String args[])
    {  
DefaultConst d=new DefaultConst();
    }
}

We define a program that begins with the construction of the “DefaultConst” Java class. The “DefaultConst” class is further defined with the constructor which is entitled the same as the name of the Java class. Here, we create this constructor which is empty but contains a print statement inside the constructor block. Then, we deploy the class main() method where this class is called. For this, we declare the “d” object and employ the DefaultConst() there. From there, the DefaultConst() is executed.

The default constructor has not given a parameter but the print statement is executed by creating its object in the main() method.

Example 2:

The demonstration of the constructor is accomplished in the prior example. Now, there is an example copy constructor. The Java copy constructors take a current object as input and produce a copy of the defined object.

class ComplexNumber {
    private double real, img;
    public ComplexNumber(double real, double img)
    {
        this.real = real;
        this.img = img;
    }
    ComplexNumber(ComplexNumbercn)
    {
        System.out.println("Inside a Copy constructor");
        real = cn.real;
        img = cn.img;
    }
    @Override public String toString()
    {
        return "(" + real + " + " + img + "i)";
    }
}
public class Main {
    public static void main(String[] args)
    {
        ComplexNumber cn1 = new ComplexNumber(3, 9);
        ComplexNumber cn2 = new ComplexNumber(cn1);
        ComplexNumber cn3 = cn2;
        System.out.println(cn2);
    }
}

We have a previous program where we create the “ComplexNumber” class of Java. The “ComplexNumber” class contains attributes that are declared as “real” and “img”. After that, we define a constructor in the “ComplexNumber” class where the class attributes are passed as arguments. Then, we use the “this” keyword to refer to the current objects, “real” and “img”. After that, we employ the “ComplexNumber()”copy constructor which has a parametric “cn” object of the “ComplexNumber” class. The constructor is declared with the objects of the class. The values of the instance variables are initialized with those from the received object.

Next, we perform a toString() override operation on the “real” and “img” class objects. The “ComplexNumber” main class is implemented with the main() method. Here, we create the “cn1” object to invoke the ComplexNumber() class. We set the values for the “real” and “img” variables in the ComplexNumber() class. After this, we declare the “cn2” object where the copy constructor is involved as the “cn2” is passed inside it. Then, we declare another “cn3” object to reference the “cn2” object. In the end, we call the toString() method of the “cn2” object to print the values.

The complex number of real and imaginary values for both the existing object and the copied object are the same. The copy constructor doesn’t affect the original date of the objects.

Example 3:

The copy constructor is just used to create a duplicate copy of the existing variables of the class. Now, the copy constructor is created for referenced type classes. Through the copy constructor, we can add the attributes of one class to another class.

class Employee
{
    private String eName;
    private double eSalary;
    private Address eAddress;
   
    Employee(String eName, double eSalary, Address eAdd)
    {
        this.eName = eName;
        this.eSalary = eSalary;
        this.eAddress = eAdd;
    }  
    Employee(Employee emp)
    {
        this.eName = emp.geteName();
        this.eSalary = emp.geteSalary();
        this.eAddress = emp.geteAddress();
    }  
    public Address geteAddress() {
        return eAddress;
    }

    public void seteAddress(Address eAddress) {
        this.eAddress = eAddress;
    }
    public String geteName() {
        return eName;
    }
    public void seteName(String eName) {
        this.eName = eName;
    }
    public double geteSalary() {
        return eSalary;
    }
    public void seteSalary(double eSalary) {
        this.eSalary = eSalary;
    }
}
class Address
{
    int postCode;
    Address(int emp)
    {
        this.postCode = emp;
    }
}
public class Main
{  
    public static void main(String[] args)
    {
        Address eAdd = new Address(100002);
        Employee emp1 = new Employee("Bella", 85000.0, eAdd);
        Employee cloneOfemp1 = new Employee(emp1);
       
        eAdd.postCode = 200003;
       
        System.out.println("Employee-1: " + emp1.geteAddress().postCode);
        System.out.print("Employee-2: " +  cloneOfemp1.geteAddress().postCode);
    }
}

The program is established with the “Employee” Java class and we set the private attributes of the class. These attributes include the string eName, double type eSalary, and the Address eAddress. Then, we construct the parameterized constructor of the “Employee” class which takes the existing class attributes as parameter objects. In the parameterized constructor, we call the k “this” keyword which references the current instance directly.

Next, we define a copy constructor which takes the “emp” parameter to reference the object of the “Employee” class. We specify the getter methods for each of the objects. After that, we call each of the getter methods and setter methods which control the value against each reference object of the class. Next, we create a program’s second class which is “Address” which has the “postCode” member. Also, we define the copy constructor inside the class which takes the reference of the Employee class object “emp” of type int. The postCode object of the “Address” class is set with the “emp” object.

Now, the “emp” object of the Employee class and the “postCode” object of the Address class provide the same data. Then, we have a “Main” class where the main() method is deployed to assign the values to the given attributes and execute them. We call the Address() class in the “eAdd” object and set the eAddress value to it. Within the “emp” object, the values for the other fields of the Employee class are also initialized. Furthermore, we declare a reference object “cloneOfemp1” that points to an “emp1” object which is generated by the new keyword called “Employee” which uses a copy constructor to copy the data from the first object.

Then, we alter the value of the address which also affects the “eAdd” clone object. The print statement displays the results of changing the value of the clone object.

The address of the copy constructor object is modified which is displayed on the Java prompt:

Example 4:

The copied object can also be created without the copy constructor by simply giving the contents of one object to the other. Let’s clone the class objects without utilizing the copy constructor.

import java.util.Scanner;

public class Product {
    public int pid;
    public float price;
    public String pname;
   
    public Product(){}
   
    public Product (int id, String pname, float price){
        this.pid = pid;
        this.pname = pname;
        this.price = price;
    }  
   
    public void productView () {
        System.out.println("product ID : " + this.pid);
        System.out.println("product Name : " + this.pname);
        System.out.println("product price : " + this.price);
    }
   
    public static void main (String[] args) {
        Scanner Myscan = new Scanner(System.in);
        System.out.println("Enter the product name");
        String pname = Myscan.next();
       
        System.out.println("Enter the product id");
        int pid = Myscan.nextInt();
       
        System.out.println("Enter the product price");
        int price = Myscan.nextInt();
       
        Product product = new Product(pid, pname, price);
       
        System.out.println("Data of the original object");
        product.productView();
       
        Product product_copy = new Product();
        product_copy.pid = product.pid;
        product_copy.price = product.price;
        product_copy.pname = product.pname;
       
        System.out.println("Data of the copied object");
        product.productView();
    }
}

The program is defined with the “Product” public class where we declare its objects which are pid, pname, and pprice of a different type. After that, we just create the constructor for the specified class with no arguments. Next, we create the parameterized constructor of the class where all the class attributes are declared as an argument. Inside the class constructor, we utilize the “this” reference variable with the class attributes which refers to the current object of the constructor.

Then, we have the “productView” function definition of the “Product” class to display or print the values of each of the class attributes. After this, we employ the main() method where we use the scanner class to get the values for the “Product” class attributes to form the user. Once the user inputs the value of the attribute, the original values for the class instance is displayed from the productView() function. Then, we create the “product_copy” object where we invoke the “Product()” class. Now, the product_copy has the content of the product class. So, we copy the attributes of the “Product” class with the new objects of the product_copy. Both the class attributes and the product_copy attribute hold the same values.

The values of the original object and the copied object are the same without using the copy constructor.

Conclusion

The copy constructors of Java are an efficient and straightforward way to duplicate the objects. They can make both shallow and deep clones. We have given an executable program of the copy constructors where the different scenarios are accomplished. Moreover, copy constructors have the disadvantage of being inherited. But we can get around this difficulty by including a method that triggers the copy constructor in the base and derived classes.

About the author

Saeed Raza

Hello geeks! I am here to guide you about your tech-related issues. My expertise revolves around Linux, Databases & Programming. Additionally, I am practicing law in Pakistan. Cheers to all of you.