34

I was going through Copy Constructors, I have gone through the links in stack over flow and others as well. But i am not clear on the following points.

  1. Why do we need a Copy Constructor
  2. When do we need a Copy Constructor

I mean what is the exact situation or scenario we would need to use Copy Constructor. Can some one explain with an example or point out links so that i can go through and understand them in clear.

Following are the links i have gone through to get an understanding of what is a copy constructor.

http://www.programmerinterview.com/index.php/java-questions/how-copy-constructors-work/

https://deepeshdarshan.wordpress.com/2013/12/05/copy-constructors-in-java/

The second link explains 'why' and 'where' the copy constructor is to be used. But still i am not clear on it.

Below is my class Employee.java

package com.test;

/**
 * @author avinashd
 *
 */
public class Employee {

    private String rollNo;
    private String name;

    //constructor
    public Employee(String rollNo, String name){

        this.rollNo = rollNo;
        this.name = name;
    }

    //copy constructor
    public Employee(Employee employee){

    this.rollNo = employee.rollNo;
    this.name = employee.name;

    }

    public String getRollNo() {
        return rollNo;
    }

    public void setRollNo(String rollNo) {
        this.rollNo = rollNo;
    }

    public String getName() {
        return name;
    }

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

Copy Constructor is used to create and exact copy of an object with the same values of an existing object.

Say for example we have an Employee with values as rollNo: 1 and name: avinash. Copy Constructor would create a similar object with values as rollNo: 1 and name: avinash . But both are 2 different objects and changes to the values of on object will not affect another object.

The Question here is

When we have a constructor such as

public Employee(String rollNo, String name){
    this.rollNo = rollNo;
    this.name = name;
}

to create an object. We can call the same constructor to create another object. But why do we need to call copy constructor.When do we need to call it ?. Please explain

soufrk
  • 825
  • 1
  • 10
  • 24
Avinash Reddy
  • 2,204
  • 3
  • 25
  • 44
  • 1
    If you don't see the point in creating such constructor, then you don't need it. – Alex Mar 31 '15 at 06:53
  • 1
    For what it's worth, the copy constructor in the above example attempts to directly access private fields. It should be `employee.getRollNo()` instead of `employee.rollNo` and `employee.getName()` instead of `employee.name`. – Makaveli84 Nov 21 '16 at 16:50
  • 1. We don't. 2. I have never used one in 21 years of Java. 3. There is really no such thing as a 'copy constructor' in Java. A copy constructor is something that can be used by a C++ compiler when passing or returning objects by value, or assigning them. None of this happens in Java. – user207421 Feb 13 '18 at 00:10
  • @Makaveli84 There's nothing wrong with accessing private fields from methods in the same class. – Jim Balter Apr 17 '22 at 17:00
  • @JimBalter It is legal, but not good practice. AFAIK, it's usually advisable to call the `get`ters and `set`ters because such methods might contain specific and/or additional implementation details beyond simple field assignments. – Makaveli84 Apr 18 '22 at 12:04
  • In which case the constructor would probably want to avoid such "additional implementation details". In any case, there are no such additional actions here. It's simply false that there's any need or reason to use getters and setters inside the class. – Jim Balter Apr 19 '22 at 17:18

8 Answers8

38

There are 2 good reasons for using a copy constructor instead of the constructor passing all parameters :

  1. when you have a complex object with many attributes it is much simpler to use the copy constructor
  2. if you add an attribute to your class, you just change the copy constructor to take this new attribute into account instead of changing every occurence of the other constructor
Markus Pscheidt
  • 6,853
  • 5
  • 55
  • 76
Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
34

Copy constructors, by convention, should provide a deep copy of objects. As already mentioned by other answers, the main convenience provided by copy constructors is when your object becomes too complex. Note that java.lang.Cloneable provides an (almost) similar declaration.

But there are a number of advantages to using copy constructors over the Cloneable interface.

  1. Cloneable as an interface does not actually provide any methods. For it to be effective, you still need to override the clone method of java.lang.Object. This is quite a counterintuitive use for an interface.

  2. clone returns an Object. For it to be of any use, you still need to typecast. This is awkward and could lead to runtime errors.

  3. The clone method is poorly documented. For clone, things can get messed up if you have final fields pointing to mutable objects.

  4. Most importantly, copy constructors can take in and deep copy instances of subclasses. IMO, this is where copy constructors really shine.

There are more advantages (see Joshua Bloch's Effective Java 2e) but these are the points which I have found most pertinent to what I have worked on so far.

[1] Nothing in the Java language actually provides a default construct for deep copying. At most, objects can just tell programmers that they can be deep copied by, say, implementing Cloneable or providing a copy constructor.

skytreader
  • 11,467
  • 7
  • 43
  • 61
5

What if you want to have another Employee instance with the exact same values as the one you already have?.

Will you call?

setName(oldEmployee.getName())..
setRollNumber(oldEmployee.getRollNumber())..
etc..

Instead of doing that, use this

Employee copyOfEmployeeOne=new Employee(employeeOneInstance);
// no need of a sequence of setters..
TheLostMind
  • 35,966
  • 12
  • 68
  • 104
  • I can call the regular constructor right. Employee copyOfEmployee = new Employee(1,avinash); . This also creates Employee object with the same values of the first object. – Avinash Reddy Mar 31 '15 at 06:49
  • 4
    @AvinashReddy - What if there are 20 attributes ?.. What if you don't know the values of 5 attributes and you will have to get them from the other instance? – TheLostMind Mar 31 '15 at 06:51
4

Copy constructors give us many advantages over Object.clone() method because they

  1. Don’t force us to implement any interface or throw an exception.
  2. Don’t require any casts.
  3. Don’t require us to depend on an unknown object creation mechanism.
  4. Don’t require parent class to follow any contract or implement anything.
  5. Allow us to modify final fields.
  6. Allow us to have complete control over object creation, we can write our initialization logic in it.

Read more on Java Cloning - Copy Constructor versus Cloning

Naresh Joshi
  • 4,188
  • 35
  • 45
2

Another case would be storing object "historical" values.

So you have single object but whenever you change its state you want to add it to ArrayList or whatever data structure fits you best, instead of making manual copy of the data you just use "copy constructor" before further modification.

zubergu
  • 3,646
  • 3
  • 25
  • 38
0

Through Copy constructor We can do cloning with out using much complex stuff like implementing Cloneable interface and overwriting clone method. Also we no need to worry specially about deep cloning.

But points to be noted are :

1.When we implement Cloneable, it is an intimation to other classes/users that this class' objects can be cloneable. With out this, Other classes may not have explicit information about cloneable.

2.If we make our copy constructor as private , then we can restrict cloning of this class' object. Then this copy constructor can only be used to initialize newly created objects in local to class rather than for cloning purpose in other class.

3.When you do not want to make your class cloneable but if you have written copy constructor with access specifier public, then it leads to insecurity that other classes can create objects of your class.

Srikant M
  • 35
  • 2
0

Copy Constructors implements both shallow and deep cloning mechanism, but main advantages of using copy constructor over cloning(using Cloneable interface) is:

  1. We don't require any type casing as of in using Object.clone()method.
  2. We will be able to modify the final fields for copying purpose unlike we are unable to modify or access final fields in case of Object.clone() mechanism.
  3. It allows us to have complete control over object creation, we can write our initialization logic in it.
  4. If we want to clone object of our class that holds reference variable of other dependent class we don't need to implement clone method that class. Simply by initializing our copy constructor, we can achieve that.
BinDev
  • 41
  • 4
0

Consider this example where super class has a copy constructor provided to implicitly force developer to manually copy fields over to parent class. This can be useful for Downcasting:

public class Employee {
    private String name;
    private int age;

    // regular constructor
    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // copy constructor
    public Employee(Employee that) {
        this.name = that.name;
        this.age = that.age;
    }
    // getters & setters
}

public class SeniorMgmt extends Employee {
    private boolean secureAccess;

    public SeniorMgmt(Employee employee, boolean secureAccess) {
        super(employee);
        this.secureAccess = secureAccess;
    }
    // getters & setters
}

public class TestDrive {
    public static void main(String[] args) {
        Employee programmer = new Employee("John", 34);
        SeniorMgmt promotedProgrammer = new SeniorMgmt(programmer, true);
    }
}
nabster
  • 1,561
  • 2
  • 20
  • 32