为什么我们需要复制构造函数以及何时应该在java中使用复制构造函数

Avi*_*ddy 34 java copy-constructor

我正在浏览Copy Constructors,我已经浏览了堆栈中的链接和其他链接.但我不清楚以下几点.

  1. 为什么我们需要一个Copy Constructor
  2. 我们何时需要复制构造函数

我的意思是我们需要使用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/

第二个链接解释了"为什么"和"在哪里"使用复制构造函数.但我仍然不清楚它.

下面是我的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

复制构造函数用于创建具有相同现有对象值的对象的精确副本.

比方说,我们有一个员工,其值为rollNo: 1name: avinash.复制构造函数将创建一个类似的对象,其值为rollNo: 1name: avinash.但两者都是2个不同的对象,对on对象的值的更改不会影响另一个对象.

这里的问题是

当我们有一个构造函数,如

public Employee(String rollNo, String name){
    this.rollNo = rollNo;
    this.name = name;
}
Run Code Online (Sandbox Code Playgroud)

创建一个对象.我们可以调用相同的构造函数来创建另一个对象.但是为什么我们需要调用copy构造函数.什么时候需要调用它?请解释

Ser*_*sta 35

使用复制构造函数而不是传递所有参数的构造函数有两个很好的理由:

  1. 当你有一个具有许多属性的复杂对象时,使用复制构造函数要简单得多
  2. 如果向类中添加属性,则只需更改复制构造函数即可将此新属性考虑在内,而不是更改其他构造函数的每个出现位置


sky*_*der 34

按照惯例,复制构造函数应该提供对象的深层副本.正如其他答案已经提到的,复制构造函数提供的主要便利是当对象变得太复杂时.请注意,java.lang.Cloneable提供(几乎)类似的声明.

但是在Cloneable接口上使用复制构造函数有许多优点.

  1. Cloneable作为接口实际上不提供任何方法.为了使它有效,你仍然需要覆盖clone方法java.lang.Object.这对于接口来说是非常违反直觉的.

  2. clone返回一个Object.为了它的任何用途,你仍然需要进行类型转换.这很尴尬,可能导致运行时错误.

  3. clone方法记录不完整.因为clone,如果你有最终字段指向可变对象,事情就会搞砸.

  4. 最重要的是,复制构造函数可以接收和深度复制子类的实例.IMO,这是复制构造者真正发挥作用的地方.

有更多的优点(参见Joshua Bloch的Effective Java 2e),但这些是我发现的与我迄今为止所做的工作最相关的要点.

[1] Java语言中没有任何内容实际上为深度复制提供了默认构造.最多,对象可以告诉程序员,可以通过实现Cloneable或提供复制构造函数来深度复制它们.


The*_*ind 5

如果您想让另一个Employee实例具有与您已有的实例完全相同的值,该怎么办?

你会打电话吗?

setName(oldEmployee.getName())..
setRollNumber(oldEmployee.getRollNumber())..
etc..
Run Code Online (Sandbox Code Playgroud)

而不是这样做,使用它

Employee copyOfEmployeeOne=new Employee(employeeOneInstance);
// no need of a sequence of setters..
Run Code Online (Sandbox Code Playgroud)

  • @AvinashReddy - 如果有20个属性怎么办?如果你不知道5个属性的值,你将不得不从另一个实例获取它们怎么办? (4认同)