clone 分为浅层clone和深层clone。
1. 浅层clone是指对象中的非对象实例,被复制过来。 修改复制对象的这些实例,并不会对原对象产生影响。比如下面例子中的salary。 但是修改复制对象中的对象实例,对原对象中的对象实例,也会产生影响,比如下面例子中的hireDay
2. 深层clone就要求,修改复制对象中的对象实例,对原对象中的对象实例,不产生影响
package entity;
import java.util.Date;
import java.util.GregorianCalendar;
public class Employee implements Cloneable{
private String name;
private double salary;
private Date hireDay;
public Employee(String name, double salary){
this.name = name;
this.salary = salary;
hireDay = new Date();
}
public Employee clone() throws CloneNotSupportedException{ //浅层clone
// call Object.clone
Employee cloned = (Employee)super.clone();
//clone mutable fields
// cloned.hireDay = (Date) hireDay.clone(); //撤掉这行的注释,那么就变成了深层clone
return cloned;
}
public void setHireDay(int year, int month, int day){
Date newHireDay = new GregorianCalendar(year, month, day).getTime();
//Example of instance field mutation
hireDay.setTime(newHireDay.getTime());
}
public void raiseSalary(double byPercent){
double raise = salary * byPercent / 100;
salary += raise;
}
public void setName(String newName){
this.name = newName;
}
public String toString(){
return "Employee[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
}
}
package main;
import entity.Employee;
public class CloneTest {
public static void main(String[] args) {
Employee original = new Employee("John Q. Public",5000);
original.setHireDay(2000, 1,1);
Employee copy = null;
try {
copy = original.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
copy.raiseSalary(10);
copy.setHireDay(2002, 12,31);
System.out.println("orignal=" + original);
System.out.println("copy=" + copy);
copy.setName("BOb");
//发现不管是浅层clone,还是深层clone,对于String类型来说,都是深层clone
// 也就是说 复制对象中String类型的改变,不会影响到原对象中的String类型
System.out.println("orignal=" + original);
System.out.println("copy=" + copy);
}
}
3. 还有一个问题,就是不管是浅层clone,还是深层clone,对String类型来说,好像都是深层clone。
原因是String类型是不可变性。具体了解请参考知乎--如何理解String类型的不可变性