浅拷贝:使用一个已知实例对新创建实例的成员变量逐个赋值,这个方式被称为浅拷贝。
深拷贝:当一个类的拷贝构造方法,不仅要复制对象的所有非引用成员变量值,还要为引用类型的成员变量创建新的实例,并且初始化为形式参数实例值。这个方式称为深拷贝.
也就是说浅拷贝只复制一个对象,传递引用,不能复制实例。而深拷贝对对象内部的引用均复制,它是创建一个新的实例,并且复制实例。
想要实现copy功能,必须要implments Cloneable
接口,重写Object.clone()
方法。
public class CloneTest {
@Test
public void test_shallow() throws CloneNotSupportedException {
UserShallow u1 = new UserShallow(1, "aa",new Date());
UserShallow u2 = (UserShallow) u1.clone();
System.out.println(u1 == u2); //false
System.out.println(u1.equals(u2)); //false
System.out.println(u1.birth == u2.birth); //true
System.out.println(u1.birth.equals(u2.birth));//true
}
@Test
public void test_deep() throws CloneNotSupportedException {
UserDeep u1 = new UserDeep(1, "aa",new Date());
UserDeep u2 = (UserDeep) u1.clone();
System.out.println(u1 == u2); //false
System.out.println(u1.equals(u2)); //false
System.out.println(u1.birth == u2.birth); //false
System.out.println(u1.birth.equals(u2.birth)); //true
}
}
//浅copy
class UserShallow implements Cloneable{
public int age;
public String name;
public Date birth;
public UserShallow(int age, String name, Date birth) {
this.age = age;
this.name = name;
this.birth = birth;
}
@Override
protected Object clone() throws CloneNotSupportedException {
UserShallow u = (UserShallow) super.clone();
return u;
}
}
//深copy
class UserDeep implements Cloneable {
public int age;
public String name;
public Date birth;
public UserDeep(int age, String name, Date birth) {
this.age = age;
this.name = name;
this.birth = birth;
}
@Override
protected Object clone() throws CloneNotSupportedException {
UserDeep u = (UserDeep) super.clone();
u.birth = (Date) this.birth.clone(); //java.util.Date实现了Cloneable
// u.name = this.name.clone(); //String 没有重写clone
return u;
}
}
总结:无论浅copy还是深copy, u1 != u2 ,且u1.equals(u2) == false
,它们已经是两个对象了(因为没有重写.equals()方法
)。