
[英]Why do we need default constructor when we can initialize data members in java?
[英]Why do we need copy constructor and when should we use copy constructor in java
我正在浏览复制构造函数,我也浏览了堆栈溢出和其他链接中的链接。 但我不清楚以下几点。
我的意思是我们需要使用 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
的 Employee 。 Copy Constructor 将创建一个类似的对象,其值为rollNo: 1
和name: avinash
。 但两者都是 2 个不同的对象,对对象值的更改不会影响另一个对象。
这里的问题是
当我们有一个构造函数比如
public Employee(String rollNo, String name){
this.rollNo = rollNo;
this.name = name;
}
创建一个对象。 我们可以调用相同的构造函数来创建另一个对象。 但是为什么我们需要调用复制构造函数。我们什么时候需要调用它?。 请解释
使用复制构造函数而不是传递所有参数的构造函数有两个很好的理由:
按照惯例,复制构造函数应该提供对象的深层副本。 正如其他答案已经提到的,复制构造函数提供的主要便利是当您的对象变得过于复杂时。 请注意, java.lang.Cloneable
提供了(几乎)类似的声明。
但是在Cloneable
接口上使用复制构造函数有许多优点。
Cloneable
作为接口实际上不提供任何方法。 为了使其有效,您仍然需要覆盖java.lang.Object
的clone
方法。 对于接口来说,这是一种非常违反直觉的用法。
clone
返回一个Object
。 为了让它有任何用处,您仍然需要进行类型转换。 这很尴尬,可能会导致运行时错误。
clone
方法的记录很差。 对于clone
,如果您有指向可变对象的 final 字段,事情可能会变得一团糟。
最重要的是,复制构造函数可以接收子类的深度复制实例。 IMO,这是复制构造函数真正闪耀的地方。
还有更多优势(请参阅 Joshua Bloch 的Effective Java 2e ),但这些是我发现与我迄今为止所做的工作最相关的要点。
[1] Java 语言中实际上没有任何内容为深度复制提供默认构造。 最多,对象只能告诉程序员它们可以通过实现Cloneable
或提供复制构造函数来进行深度复制。
如果您想要另一个Employee
实例与您已有的实例具有完全相同的值,该怎么办?
你会打电话吗?
setName(oldEmployee.getName())..
setRollNumber(oldEmployee.getRollNumber())..
etc..
而不是这样做,使用这个
Employee copyOfEmployeeOne=new Employee(employeeOneInstance);
// no need of a sequence of setters..
与 Object.clone() 方法相比,复制构造函数为我们提供了许多优势,因为它们
阅读有关Java 克隆的更多信息- 复制构造函数与克隆
另一种情况是存储对象“历史”值。
因此,您只有一个对象,但是每当您更改其状态时,您都想将其添加到ArrayList
或任何最适合您的数据结构中,而不是手动复制数据,您只需在进一步修改之前使用“复制构造函数”。
通过复制构造函数我们可以在不使用很多复杂的东西的情况下进行克隆,比如实现 Cloneable 接口和覆盖克隆方法。 我们也无需特别担心深度克隆。
但需要注意的是:
1.当我们实现Cloneable时,是对其他类/用户的一个提示,该类的对象可以是可克隆的。 没有这个,其他类可能没有关于可克隆的明确信息。
2.如果我们将我们的复制构造函数设为私有,那么我们可以限制对此类对象的克隆。 那么这个复制构造函数只能用于在类本地初始化新创建的对象,而不能用于其他类中的克隆目的。
3.当您不想使您的类可克隆时,如果您编写了带有访问说明符 public 的复制构造函数,则会导致其他类可以创建您类的对象的不安全性。
Copy Constructors 实现了浅层和深层克隆机制,但使用拷贝构造函数优于克隆(使用 Cloneable 接口)的主要优点是:
考虑这个示例,其中超类提供了一个复制构造函数,以隐式强制开发人员手动将字段复制到父类。 这对于向下转换很有用:
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.