今天在做clone实验时遇到一个奇怪的问题,根据《java核心技术第一卷》的叙述,如果一个对象需要clone,而且其内部还存在可变(一般为引用类型)类型的数据,那么这个可变类型的数据在克隆时也需要调用自己的clone方法,如代码中的Employee2中的clone方法中的注释部分,否则为浅度克隆,但是根据自己的实验,在Employee2中的方法并没有调用Date方法中的clone方法(被注释的代码//employee2.hireDay=(Date)hireDay.clone();),但是程序的运行结果表明Date类型已经被深度克隆了,而Employee2中的clone方法中如果不调用的Employee3的clone方法(即employee2.employee3=(Employee3)employee3.clone();),那么employee3对象不会被深度克隆。
至此,我的问题是为什么java自带的类不需要调用clone方法就能实现深度克隆,而自己写的类必须调用clone方法才能实现此功能,但根据书中的描述,Date类也必须调用自己的clone方法才能深度克隆。希望有朋友能告诉我,谢谢。以下为全部代码:
import java.util.*;
public class CloneTest
{
public static void main (String[] args) throws CloneNotSupportedException
{
Employee2 harry=new Employee2("Harry Hacke",3500,1989,10,1);
harry.setEmployee3(new Employee3("Harry Hacke",3500,1989,10,1));
Employee2 harry2=(Employee2)harry.clone();
harry2.getEmployee3().setName("yyyyyyyy");
harry.getEmployee3().setName("yyyyyyyy1111");
harry.setHireDay(new Date());
harry.setSalary(5566);
harry2.setName("ddddd");
System.out.println (harry);
System.out.println (harry2);
System.out.println (harry.getEmployee3().getName());
System.out.println (harry2.getEmployee3().getName());
}
}
class Employee2 implements Cloneable //Employee 继承了SerialCloneable 就有他的克隆方法
{
@Override
protected Object clone() throws CloneNotSupportedException {
Employee2 employee2=(Employee2)super.clone();
//根据书中的描述,Date类也必须调用自己的clone方法才能实现深度克隆,但此处并没有调用hireDay的clone方法竟然也实现了深度克隆
//employee2.hireDay=(Date)hireDay.clone();
employee2.employee3=(Employee3)employee3.clone();
return employee2;
}
private String name;
private double salary;
private Date hireDay;
public Employee2(String n,double s,int year,int month,int day)
{
name=n;
salary=s;
GregorianCalendar calendar=new GregorianCalendar(year,month-1,day);
hireDay=calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public String toString()
{
return getClass().getName()+" name:"+name
+" salary"+salary
+" hireDay:"+hireDay;
}
public void lixi(double b)
{
double aa=salary*b/100;
salary+=aa;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void setHireDay(Date hireDay) {
this.hireDay = hireDay;
}
Employee3 employee3;
public Employee3 getEmployee3() {
return employee3;
}
public void setEmployee3(Employee3 employee3) {
this.employee3 = employee3;
}
}
class Employee3 implements Cloneable //Employee 继承了SerialCloneable 就有他的克隆方法
{
@Override
protected Object clone() throws CloneNotSupportedException {
// TODO Auto-generated method stub
return super.clone();
}
private String name;
private double salary;
private Date hireDay;
public Employee3(String n,double s,int year,int month,int day)
{
name=n;
salary=s;
GregorianCalendar calendar=new GregorianCalendar(year,month-1,day);
hireDay=calendar.getTime();
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public Date getHireDay()
{
return hireDay;
}
public String toString()
{
return getClass().getName()+" name:"+name
+" salary"+salary
+" hireDay:"+hireDay;
}
public void lixi(double b)
{
double aa=salary*b/100;
salary+=aa;
}
public void setName(String name) {
this.name = name;
}
public void setSalary(double salary) {
this.salary = salary;
}
public void setHireDay(Date hireDay) {
this.hireDay = hireDay;
}
}