1.为什么要克隆?
假如有一个Person类,通常的做法是进行赋值,如Person p2=p1,这个时候只是简单了copy了一下reference,p1和p2都指向内存中同一个object,这样p1或者p2的一个操作都可能影响到对方。比如在p2中对Person中的某个参数进行了修改,P1所中的相应参数也会有所改动,这显然是我们不愿意看到的。如果要做到互不影响,我们希望得到p2的一个精确拷贝,同时两者互不影响,这时候我们就可以使用Clone来满足我们的需求。Person p2=tp1.clone(),这时会生成一个新的Person 对象,并且和p1具有相同的属性值和方法。
2.浅度克隆(shadow clone)&深度克隆(deep clone)
Cloneable
{
public Object clone() throws CloneNotSupportedException
{
Employee cloned = (Employee) super.clone();
cloned.hireDay = (Date) hireDay.clone()
return cloned;
}
b. 调用Clone()方法的对象所属的类(Class)必须implements Clonable接口,否则在调用Clone方法的时候会抛出CloneNotSupportedException。
下面讲举一个clone的例子:
int age;
String name;
public Friend(int age, String name) {
this.age = age;
this.name = name;
}
public Object clone () throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable {
int age;
/* *
*String 类型特殊,因为他为引用型,而且他指向的值为常量,克隆出来的对象改变他的
*值实际上是改变了克隆出来对象String类型成员的指向不会影响被克隆对象的值及其指向?
*因为引用被克隆了,我改变的是引用的指向!
*/
String name;
Friend f;
public Person(int age, String name, Friend f) {
this.age = age;
this.name = name;
this.f = f;
}
public Object clone () throws CloneNotSupportedException {
Person p = (Person)super.clone();
p.f = (Friend)p.f.clone();
return p;
}
public String toString(){
StringBuffer sb = new StringBuffer();
return super.toString()+sb.append("age=").append(age).
append(",name=").append(name).
append("friend=").append("f.name=").
append(f.name).append("f.age=").append(f.age).toString();
}
}
public class Clonetest {
public static void main(String [] args) throws CloneNotSupportedException {
Person p = new Person(4,"haha",new Friend(5,"hehe"));
Person p1 = (Person)p.clone();
p1.name = "oop";
p1.age = 10;
p1.f.name = "ooad";
p1.f.age = 56;
System.out.println (p);
System.out.println (p1);
}
输出结果为:
---------- java ----------
Person@d9f9c3age=4,name=hahafriend=f.name=hehef.age=5
Person@9cab16age=10,name=oopfriend=f.name=ooadf.age=56
Normal Termination
输出完成(耗时 1 秒)。
此程序中的输出不知道为什么会是这样,后来查了资料发现是和toString有关。下篇将总结一下toString的用法。
这篇文章我是没有耐心看了,不过最近又看了一下浅度拷贝和深度拷贝,可以这样来说吧,举例子子,有一个Book类,里面有三个属性String bname,double price,Person author。发现了吧,这里面的author是另一个Person类。Book有创建了两个实例,b1和b2。当执行b2=b1.clone()后,更改了b2中author的属性值,你会发现b1中author的属性值也会改变,为什么呢?因为这是浅拷贝,要在override的clonable()方法里把Person方法一起拷贝,这样,即使改变了b2中author的属性值了b1中author的属性值也不会改变,这就是深度拷贝了。例子不写了,呵呵(写给自己看的,对不住了)