我正在浏览Copy Constructors,我已经浏览了堆栈中的链接和其他链接。但我不清楚以下几点。
我的意思是我们需要使用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;
}
}
复制构造函数用于创建具有相同现有对象值的对象的精确副本。
比方说,我们有一个员工,其值为rollNo: 1
和name: avinash
。复制构造函数将创建一个类似的对象,其值为rollNo: 1
和name: avinash
。但两者都是2个不同的对象,对on对象值的更改不会影响另一个对象。
这里的问题是
当我们有一个构造函数,如
public Employee(String rollNo, String name){
this.rollNo = rollNo;
this.name = name;
}
创建一个对象。我们可以调用相同的构造函数来创建另一个对象。但是为什么我们需要调用copy构造函数。什么时候需要调用它?请解释
答案 0 :(得分:31)
使用复制构造函数而不是传递所有参数的构造函数有两个很好的理由:
答案 1 :(得分:30)
按照惯例,复制构造函数应该提供对象的深层副本。正如其他答案已经提到的,复制构造函数提供的主要便利是当对象变得太复杂时。请注意,java.lang.Cloneable
提供(几乎)类似的声明。
但是在Cloneable
接口上使用复制构造函数有很多优点。
Cloneable
作为接口实际上并不提供任何方法。为了使其有效,您仍需要覆盖clone
的{{1}}方法。这对于界面来说是非常违反直觉的。
java.lang.Object
返回clone
。为了它的任何用途,你仍然需要进行类型转换。这很尴尬,可能会导致运行时错误。
Object
方法的记录很少。对于clone
,如果最终字段指向可变对象,事情就会搞砸。
最重要的是,复制构造函数可以接收和深度复制子类的实例。 IMO,这是复制构造者真正发挥作用的地方。
还有更多的优势(参见Joshua Bloch的 Effective Java 2e ),但这些是我发现的与我迄今为止所做的工作最相关的要点。
[1] Java语言中没有任何内容实际上为深度复制提供了默认构造。最多,对象可以告诉程序员,可以通过实现clone
或提供复制构造函数来深度复制它们。
答案 2 :(得分:5)
如果您希望另一个Employee
实例具有与您已有的实例完全相同的值,该怎么办?
你会打电话吗?
setName(oldEmployee.getName())..
setRollNumber(oldEmployee.getRollNumber())..
etc..
而不是这样做,请使用此
Employee copyOfEmployeeOne=new Employee(employeeOneInstance);
// no need of a sequence of setters..
答案 3 :(得分:2)
另一种情况是存储对象“历史”值。
所以你有单个对象,但每当你改变它的状态时,你想把它添加到ArrayList
或任何最适合你的数据结构,而不是手动复制数据,你只需要使用“复制构造函数”修改。
答案 4 :(得分:2)
复制构造函数比Object.clone()方法具有许多优点,因为它们
答案 5 :(得分:0)
通过复制构造函数我们可以使用诸如实现Cloneable接口和覆盖克隆方法之类的复杂内容来进行克隆。我们也不需要特别担心深度克隆。
但需要指出的是:
1.当我们实施Cloneable时,对于其他类/用户来说,这个类是'对象可以克隆。除此之外,其他类可能没有关于cloneable的明确信息。
2.如果我们将我们的复制构造函数设为私有,那么我们可以限制克隆这个类'宾语。然后,此复制构造函数只能用于在本地到类中初始化新创建的对象,而不是用于在其他类中进行克隆。
3.当你不想让你的类可以克隆时,如果你有一个带有访问说明符public的写复制构造函数,那么它会导致其他类可以创建你的类对象的不安全感。
答案 6 :(得分:0)
复制构造函数实现浅层和深层克隆机制,但使用复制构造函数而非克隆(使用Cloneable接口)的主要优点是:
答案 7 :(得分:0)
考虑此示例,其中超类具有提供的复制构造函数,以隐式强制开发人员将字段手动复制到父类。这对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);
}
}