Copy Constructor in Java with Examples

Get Job-ready: Java Course with 45+ Real-time Projects! - Learn Java

In C++ there is a concept of copy constructor. Similarly, Java also supports Copy constructors but the difference is that in C++ the copy constructor is created by default while in Java we have to create the copy constructor on our own. In this article, we will see how to create a copy constructor and why it is necessary in our programs.

What are Constructors in Java?

Before learning about copy constructors, we need to understand the concept of constructors. Constructors are special methods that have the same name as the class. Using constructors we can initialize global variables. Constructors do not have any return type. They are called automatically when an object is declared for that class. Constructors occupy space according to the variables present in them.

Types of Java Constructors:

1. Default Constructor in Java

Constructors which do not have a parameter list are known as default constructor.

Example of Default Constructor:

package com.DataFlair.CopyConstructor;
public class DefaultConstructor
{ 
    DefaultConstructor()
    {
        System.out.println("Object Created, so Constructor Called");
    }    
    public static void main(String args[])
    {   
        DefaultConstructor d=new DefaultConstructor(); 
    }
}

The output of the above code:

Object Created, so Constructor Called

2. Parameterized Constructor in Java

These are the Constructors which have a parameter list in it.

Example of Parameterized Constructor:

package com.DataFlair.CopyConstructor;
public class ParameterConstructor
{
    int id;  
    String name;
    ParameterConstructor(int i,String n){  
    id = i;  
    name = n;  
    }  
    void display()
    {
        System.out.println(id+" "+name);
    }
    public static void main(String args[]){   
    ParameterConstructor P = new ParameterConstructor(1,"Arka");
    P.display();  
   }  
}  

The output of the above Code:

1 Arka

Other than these two Constructors, Java also supports Copy Constructors, we will discuss it in detail now.

What is a Copy Constructor in Java?

As the name suggests, Copy Constructor is used to create a copy of a previously existing object present in the class. It is a special type of constructor that returns a duplicate copy of another object.
In C language, the copy constructor is declared automatically, but in Java, we have to create the method separately.

Why is it required to use Java Copy Constructor?

The main purpose of a copy constructor is to create a copy of an object. This helps in the reusability of code. Sometimes we might be required to use a copy of an object with minor changes, without reflecting it to the original one, for such scenarios a copy constructor is essential.

Creating a Copy Constructor in Java

The steps to create a copy constructor are as follows:

Step 1: We have to create a constructor that takes an object as a parameter. Make sure that the object belongs to the same class.

public class Interns  
{   
private int ID;   
private String name;    
public Interns(Interns interns)//copy constructor  
{   
//getters  
}   
}  

Step 2: Using getters copy each variable of the copied object to the new instances.

public class Interns  
{   
private int ID;   
private String name;    
public Interns(Interns interns)//copy constructor  
{   
this.ID=interns.ID;//getters  
this.name=interns.name;//getters
}   
}

How to Copy Mutable Type data in Java?

To copy mutable type data, we have to create a deep copy instead of a shallow copy which we did in the previous example.

Let us understand this with a code:

Code to understand Mutable data with copy constructor:

public class Interns
{
        private int ID;
        private String name;
        private Date InternDate;//Mutable Data

        public Interns( Interns interns )
        {
                this.roll = interns.id;
                this.name = interns.name;
                this.InternDate = new Date(interns.InternDate.getTime());//Deep Copy
        }
}

Code to Explain the working of Copy Constructor:

package com.DataFlair.CopyConstructor;
public class Interns
{  
    private int ID;   
    private String Name; 
    Interns(int id, String name)//parameterized constructor
    {
        ID=id;
        Name=name;
    }
    Interns(Interns interns)//copy constructor  
    {   
        System.out.println("The Copy Constructor Starts here");
        ID=interns.ID;//getters  
        Name=interns.Name;//getters
    }   
    int showID()
    {
        return ID;
    }
    String showName()
    {
        return Name;
    }
    public static void main(String[] args)
    {
        Interns I=new Interns(1,"Arka");
        System.out.println("ID of Intern: "+ I.showID()+ " Name of Intern:"+ I.showName());
        Interns IC=new Interns(I);
        System.out.println("ID of Intern: "+ I.showID()+ " Name of Intern:"+ I.showName());
    }
}

The Output of the above Program:

ID of Intern: 1 Name of Intern:Arka
The Copy Constructor Starts here
ID of Intern: 1 Name of Intern:Arka

Advantages of Using Copy Constructor in Java

  • The copy constructor can be used to change the state of a variable from final to normal.
  • In Copy Constructor there is no need for Type Casting.
  • We can change the copied object without hampering the original object.
  • It reduces the size of the code.
  • It enhances code reusability.
  • Copy Constructor is easier when there are several fields in it.

To understand the advantage of a copy constructor, let us try to copy an object without using a copy constructor.

Code for creating a copy of an object without using Copy Constructor:

package com.DataFlair.CopyConstructor;
public class Intern
{
     private int ID;
     private String name;
  Intern(int id, String Name)
  { 
    ID = id;
    name= Name;
  }
  
  Intern()
  {  
  }
  int printID()
  {
    return ID;
  }
  String printName()
  {
    return name;
  }
  public static void main(String[ ] args)
  {
    Intern I1 = new Intern(1, "Arka");
    System.out.println("ID of Intern: "+ I1.printID());
    System.out.println("Name of Intern: "+ I1.printName());

    Intern I2 = new Intern();
    I2.ID= I1.ID;
    I2.name= I1.name;

    System.out.println("Copied ID of Intern: "+ I2.printID());
    System.out.println("Copied Name of Intern: "+ I2.printName());
}
}

The output of the above code:

ID of Intern: 1
Name of Intern: Arka
Copied ID of Intern: 1
Copied Name of Intern: Arka

So, we can clearly see that the size of the code increased considerably for only 2 variables. Now, imagine if there are 50 such variables how hard it will be to copy each variable separately. So, we can see why a copy constructor is an important concept to write optimal code.

Best Practices for Copy Constructors

When crafting copy constructors, here are some valuable guidelines to consider:

  • Deep vs. Shallow Copying: Be mindful of whether you require a deep copy or a shallow copy. A deep copy replicates the entire object structure, including mutable references. A shallow copy duplicates the object’s state, but references to mutable objects point to the same underlying instances in memory. Utilise deep copying when essential to ensure modifications to the copy don’t affect the original object.
  • Final Fields: Copy constructors provide the ability to modify final fields during the copying process. This can be useful in specific scenarios, but exercise caution to avoid unintended consequences.

Difference Between Java Copy Constructor and Clone() Method:

Clone() is also a method using which we can create a duplicate copy of a pre-existing object. But using a clone method is more difficult compared to a copy constructor, due to the following reasons:

1. The clone method may throw an exception if the cloneable is not imported properly. Handling an exception is an extra task. While the Copy Constructor does not throw any such exceptions.

2. Using Clone() we cannot assign values to variables that are declared final. As we all know by now that copy constructor allows us to change the value of final variables.

3. In Clone() method typecasting is required, while in the copy constructor typecasting is not required.

Inheritance Issues in Java Copy Constructor:

One very big disadvantage of Copy Constructor is that the subclasses of the parent class which contains the copy constructor, cannot access the copy constructor. The program will give a casting error when we try to compile it.

Code explaining the Problem with inheritance and copy constructor:

package com.DataFlair.CopyConstructor;
import java.util.List;

public class TechWriter extends Interns
{
private List<Interns> Articles;
public TechWriter(TechWriter techwriter)
{
            super(techwriter.ID, techwriter.name);
            this.Articles = Articles.stream().collect(Collectors.toList());
}
}

The above code will give an error, as the compiler will not be able to recognize the variables ID and name. To fix this we have to typecast the variable with the subclass.

For Example:

Interns clone = new TechWriter((Techwriter)interns);

We can avoid typecasting by adding a new inherited method to both classes.

Code explaining how to avoid type casting in case of inherited copy constructor:

public class Interns
{
public Interns copy()
{
            return new Interns(this);
      }
}
 
public class Techwriter extends Interns
{
@Override
      public Interns copy() 
{
            return new Techwriter(this);
      }
}

Quiz on Java Copy Constructor

Common Use Cases for Copy Constructors

Copy constructors offer a versatile mechanism for object duplication in various situations. Here are a few examples:

  • Passing Objects to Methods: When passing objects to methods, you might want to create a copy to prevent unintended alterations to the original object. The copy constructor facilitates this by generating a duplicate that can be safely modified within the method.
  • Defensive Copying: In scenarios where you receive external data that may be corrupt or tampered with, creating a copy using the copy constructor allows you to work with a safe replica, protecting your core application logic.
  • State Management: Copy constructors can be instrumental in implementing the memento pattern, a software design pattern that facilitates reverting an object to a previous state. By creating a copy using the copy constructor, you can preserve a specific object state for potential restoration.

Conclusion:

Java constructors are one of the most important concepts when it comes to writing effective code. In this article, we saw how a copy constructor can be declared manually in Java. We also saw the importance, advantages and disadvantages of using copy constructors.

You give me 15 seconds I promise you best tutorials
Please share your happy experience on Google

courses

DataFlair Team

DataFlair Team is a group of passionate educators and industry experts dedicated to providing high-quality online learning resources on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. With years of experience in the field, the team aims to simplify complex topics and help learners advance their careers. At DataFlair, we believe in empowering students and professionals with the knowledge and skills needed to thrive in today’s fast-paced tech industry. Follow us for Free courses, expert insights, tutorials, and practical tips to boost your learning journey.

Leave a Reply

Your email address will not be published. Required fields are marked *