假设有一个包含5个Employee对象的EmployeeList。
我想执行该EmployeeList的克隆以创建一个新的EmployeeList,我想知道该怎么做?
以下是我的班级员工:
public class Employee {
private String name;
private String ssn;
private double salary;
private String name() {
return name;
}
private void name(String name) {
this.name = name;
}
private String ssn() {
return ssn;
}
private void ssn(String ssn) {
this.ssn = ssn;
}
private double salary() {
return salary;
}
private void salary(double salary) {
this.salary = salary;
}
void initialize(String initName, String initSsn, double initSalary) {
this.name(initName);
this.ssn(initSsn);
this.salary(initSalary);
}
public Employee(String name, String ssn, double salary) {
this.initialize(name, ssn, salary);
}
public Employee clone() {
return new Employee(this.name, this.ssn, this.salary);
}
}
以下是我的类EmployeeList:
public class EmployeeList implements Cloneable {
private Employee[] list;
private int MAX = 5;
public EmployeeList() {
list = new Employee[MAX];
for (int i = 0; i < MAX; i++)
list[i] = null;
}
public void add(Employee employee) {
list[count] = employee;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException c) {
System.out.println(c);
return null;
}
}
}
我缩短了代码,因此更容易看到。
我的问题是:
当我执行副本时,我认为它使用指向原始Employee对象的指针复制了EmployeeList。因为当我更改原始对象时,新列表中的对象也会更改
无论如何我能解决这个问题吗?
非常感谢。
答案 0 :(得分:1)
是的,它确实完成了你的想法 - 它克隆了你的数组,包括它的值。在这种情况下,数组值是指向Employee实例的指针,因此您有第二个数组指向相同的Employees。它被称为浅拷贝。如果你想要一份完整的副本,你需要像
这样的东西public Object clone() {
try {
EmployeeList copy = (EmployeeList) super.clone();
if (list!=null) {
copy.list = new Employee[list.length];
for (int i=0; i<list.length; i++) {
copy.list[i] = (Employee)list[i].clone();
}
} else {
copy.list = null;
}
return copy;
} catch (CloneNotSupportedException c) {
System.out.println(c);
return null;
}
}
您还需要使员工克隆。
通常当你处理一个对象图时,每个对象的clone()方法需要递归地克隆它的数据成员,直到你遇到基元(如你的double
)或不可变的类(一旦构造就无法改变的类 - 如{{ 1}}在你的情况下)
答案 1 :(得分:0)
在您EmployeeList.cone()
中,在调用super.clone()
的情况下进行浅层复制,您应该迭代列表元素并在每个clone()
对象上调用Employee
,例如伪代码如下:
EmployeeList.clone() {
EmployeeList newList = (EmployeeList) super.clone();
int i=0;
for (Employee emp: this.list){
newList[i++] = (Employee) emp.clone();
}
return newList;
}
不使用Cloneable
的其他选项是使用Serializable
接口并使用Apache commons SerializationUtils等实用程序深度克隆对象http://commons.apache.org/lang/api-2.3/org/apache/commons/lang/SerializationUtils.html#clone%28java.io.Serializable%29