请多多指教 一道关于clone的问题 我们有一个雇员类,请编写一段代码提供这个类的深克隆方法并检验。Class Employee { String name; double salary; Date hireDay;}我还在实习 敬请大家多多指教了 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 我是这样写的好像理解得不对 因为e2的输出 都是null 0 nullimport java.util.Date;public class DeepClone { public static void main(String[] args) throws CloneNotSupportedException { Date d = new Date(); Employee e = new Employee("Amy", 2000, d); Employee e2 = (Employee) e.clone(); System.out.println(e2.name + " " + e2.salary + " " + e2.hireDay); }}class Employee implements Cloneable { String name; double salary; Date hireDay; Employee(String name, double salary, Date hireDay) { System.out.println("name " + name + " salary " + salary + " hireDay " + hireDay); } public Object clone() throws CloneNotSupportedException { Employee cloned = (Employee) super.clone(); return cloned; }}输出结果:name Amy salary 2000.0 hireDay Mon Dec 24 15:47:40 CST 2007null 0.0 null 楼主,你的程序错误在于构造方法没有定义好。import java.util.Date;public class DeepClone { public static void main(String[] args) throws CloneNotSupportedException { Date d = new Date(); System.out.println(d); Employee e = new Employee("Amy", 2000, d); Employee e2 = (Employee) e.clone(); System.out.println(e2.name + " " + e2.salary + " " + e2.hireDay); }}class Employee implements Cloneable { String name; double salary; Date hireDay; Employee(String name1, double salary1, Date hireDay1) { name=name1;salary=salary1;hireDay=hireDay1; // System.out.println("name " + name + " salary " + salary + " hireDay " //+ hireDay); } public Object clone() throws CloneNotSupportedException { String tempName=new String(name); Date tempDate=(Date)hireDay.clone(); double tempSalary=salary; Employee t=new Employee(tempName,tempSalary,tempDate); System.out.println(t.toString()); return t; }} 还有,你的程序的clone方法里定义的仍然是浅拷贝,不是深拷贝。正确定义如上。 深拷贝要重写object类的hashcode方法和equals方法才行 lixkyx 谢谢你 可是我没明白 为什么这三个变量赋值方式都不一样呢 String tempName=new String(name); Date tempDate=(Date)hireDay.clone(); double tempSalary=salary; to Spirit_Java : 必须得重写那两个方法吗? 2楼的没写 也实现了深克隆吧 你原来的程序只是浅拷贝,不能达到目的的。为什么这三个成员变量的拷贝方式不一样,主要原因是成员变量的类型不同。因为Java的赋值语句执行的都是值的传递:对于基本数据类型的成员变量,把原本对象成员变量的值赋给副本对象对应的成员变量就可以了;对于对象类型的成员变量,把原本对象成员变量的值赋给副本对象对应的成员变量实际上复制的是引用,其结果是两个对象具有相同的实体,实际上就是一个对象有了两个名字而已!例如date1=date; 其结果是:两个名字date和date1同时指向一个实体,显然这是不符合要求的。Java的默认的clone方法,就是把原本对象的值直接付给副本对象,它实现的就是浅拷贝。所以,你的clone方法肯定是错误的。因此,你的类里面的成员变量hireDay不能直接赋值,而考虑到Date类本身不再含有对象,所以,它调用clone方法,可以返回一个独立的副本对象。因此,成员对象hireDay可以使用clone方法获取副本(但是你的主类Deepclone对象不行!)至于name成员变量,这是一个特例,本来原则上它也是一个对象,应该按照hireDay成员变量类似的方法处理,不过,String类定义了一个拷贝构造方法,可以利用已有的一个对象来创建一个副本对象(一般的类都没有定义拷贝构造方法),即上面的语句使用的办法。 import java.util.Date;public class DeepClone { public static void main(String[] args) throws CloneNotSupportedException { Date d = new Date(); Employee e = new Employee("Amy", 2000, d); Employee e2 = (Employee) e.clone(); System.out.println( e ); System.out.println(e2); }}class Employee implements Cloneable { String name; double salary; Date hireDay; Employee(String name, double salary, Date hireDay) { this.name = name; this.salary = salary; this.hireDay = (Date)hireDay.clone(); }/** @return null if it clone is not supported, otherwise return the cloned object*/ public Object clone() { Employee cloned = null; try { cloned = (Employee) super.clone(); cloned.hireDay = (Date)this.hireDay.clone(); } catch( CloneNotSupportedException cnse ) { } return cloned; } public String toString() { return "name " + name + " salary " + salary + " hireDay "+ hireDay; } }clone也有一点学问的。 楼主可以试着找本书看。 当clone() method 被call的时候, constructor是不会被call的。 它跟new 是不一样的。 所以2楼是错的。 就算你吧constructor里面的所有statements全部删掉还是可以clone 的, 只是cloned会是String double 和Date的初始值 补充: 如果你把Constructor里面的东西全部拿掉, 记得把这句 也 拿掉:cloned.hireDay = (Date)this.hireDay.clone();因为那时hireDay会是null to notwizard:大体明白了 关键在这句 cloned = (Employee)super.clone(); 刚刚在core java上找到了answer~thank you!~~ to lixkyx :恩 解释得好详细啊!理解了!非常感谢! 我是Employee的构造函数没写对啊~ 求一正则表达式 怎么知道一个类运行时用到了jdk的哪些类 如何以标点截取字符串再进行比较 BufferedInputStream 和 Scanner 有什么不同啊? timer 问题请教 使用log4j如何动态产生日志文件??? 如何用java来打开指定路径和文件名的文档、图片或声音文件 超菜问题,在线等 为什么我的文件写不进去??请各位帮我看看 高手请看:请问java如何将一个逻辑表达式解析或拆分 jfreechart画的时序图横轴坐标能实现24小时制吗 这是一个类库中已有的类 的 问题
好像理解得不对 因为e2的输出 都是null 0 nullimport java.util.Date;public class DeepClone {
public static void main(String[] args) throws CloneNotSupportedException {
Date d = new Date();
Employee e = new Employee("Amy", 2000, d);
Employee e2 = (Employee) e.clone();
System.out.println(e2.name + " " + e2.salary + " " + e2.hireDay); }
}class Employee implements Cloneable {
String name; double salary; Date hireDay; Employee(String name, double salary, Date hireDay) {
System.out.println("name " + name + " salary " + salary + " hireDay "
+ hireDay);
} public Object clone() throws CloneNotSupportedException {
Employee cloned = (Employee) super.clone();
return cloned;
}
}
输出结果:
name Amy salary 2000.0 hireDay Mon Dec 24 15:47:40 CST 2007
null 0.0 null
import java.util.Date;public class DeepClone {
public static void main(String[] args) throws CloneNotSupportedException {
Date d = new Date();
System.out.println(d);
Employee e = new Employee("Amy", 2000, d);
Employee e2 = (Employee) e.clone();
System.out.println(e2.name + " " + e2.salary + " " + e2.hireDay); }
}class Employee implements Cloneable {
String name; double salary; Date hireDay; Employee(String name1, double salary1, Date hireDay1) {
name=name1;salary=salary1;hireDay=hireDay1;
// System.out.println("name " + name + " salary " + salary + " hireDay "
//+ hireDay);
} public Object clone() throws CloneNotSupportedException {
String tempName=new String(name);
Date tempDate=(Date)hireDay.clone();
double tempSalary=salary;
Employee t=new Employee(tempName,tempSalary,tempDate);
System.out.println(t.toString());
return t;
}
}
String tempName=new String(name);
Date tempDate=(Date)hireDay.clone();
double tempSalary=salary;
必须得重写那两个方法吗?
2楼的没写 也实现了深克隆吧
因为Java的赋值语句执行的都是值的传递:
对于基本数据类型的成员变量,把原本对象成员变量的值赋给副本对象对应的成员变量就可以了;
对于对象类型的成员变量,把原本对象成员变量的值赋给副本对象对应的成员变量实际上复制的是引用,其结果是两个对象具有相同的实体,实际上就是一个对象有了两个名字而已!例如
date1=date; 其结果是:两个名字date和date1同时指向一个实体,显然这是不符合要求的。
Java的默认的clone方法,就是把原本对象的值直接付给副本对象,它实现的就是浅拷贝。所以,你的clone方法肯定是错误的。因此,你的类里面的成员变量hireDay不能直接赋值,而考虑到Date类本身不再含有对象,所以,它调用clone方法,可以返回一个独立的副本对象。因此,成员对象hireDay可以使用clone方法获取副本(但是你的主类Deepclone对象不行!)
至于name成员变量,这是一个特例,本来原则上它也是一个对象,应该按照hireDay成员变量类似的方法处理,不过,String类定义了一个拷贝构造方法,可以利用已有的一个对象来创建一个副本对象(一般的类都没有定义拷贝构造方法),即上面的语句使用的办法。
public static void main(String[] args) throws CloneNotSupportedException {
Date d = new Date();
Employee e = new Employee("Amy", 2000, d);
Employee e2 = (Employee) e.clone();
System.out.println( e );
System.out.println(e2); }
}class Employee implements Cloneable {
String name;
double salary;
Date hireDay;
Employee(String name, double salary, Date hireDay) {
this.name = name;
this.salary = salary;
this.hireDay = (Date)hireDay.clone();
}
/** @return null if it clone is not supported, otherwise return the cloned object
*/
public Object clone() {
Employee cloned = null;
try {
cloned = (Employee) super.clone();
cloned.hireDay = (Date)this.hireDay.clone();
} catch( CloneNotSupportedException cnse ) {
}
return cloned;
} public String toString()
{
return "name " + name + " salary " + salary + " hireDay "+ hireDay;
}
}clone也有一点学问的。 楼主可以试着找本书看。 当clone() method 被call的时候, constructor是不会被call的。 它跟new 是不一样的。 所以2楼是错的。 就算你吧constructor里面的所有statements全部删掉还是可以clone 的, 只是cloned会是String double 和Date的初始值
cloned.hireDay = (Date)this.hireDay.clone();
因为那时hireDay会是null
大体明白了 关键在这句 cloned = (Employee)super.clone();
刚刚在core java上找到了answer~
thank you!~~
恩 解释得好详细啊!
理解了!非常感谢!