简介
Cloneable接口是java.lang包下的接口,Cloneable其实是一个标记接口,只在实现这个接口后,我们才能重写object类中的clone()方法。clone也是首先分配内存,这里分配的内存与调用clone方法对象的内存相同,然后将源对象中各个变量的值,填充到新的对象中,填充完成后,clone方法返回一个新的地址,这个新地址的对象与源对象相同,只是地址不同。
浅拷贝
class Money implements Cloneable{
public double money = 18.8;
}
class Student1 implements Cloneable{
public int id = 1234;
public Money m = new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Student1 student1 = new Student1();
Student1 student2 = (Student1)student1.clone();
System.out.println(student1.m.money);
System.out.println(student2.m.money);
System.out.println("==================");
student2.m.money = 25.5;
System.out.println(student1.m.money);
System.out.println(student2.m.money);
}
}
//输出结果
//18.8
//18.8
//==================
//25.5
//25.5
此处我们可以看到,在完成拷贝后对student2的money进行修改,student1的money也被修改,这是因为进行的是浅拷贝。
大致是这样的,student2在另一份空间克隆了student1,但是对其中的m引用只是进行了地址的值的复制,并没有在另一份空间克隆m。而想要对m也进行克隆,我们就用到了深拷贝。
深拷贝
深拷贝就是将对象中的引用的变量的值也生成新的引用。
代码实现如下:
class Money implements Cloneable{
public double money = 18.8;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Student1 implements Cloneable{
public int id = 1234;
public Money m = new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
Student1 tmp = (Student1)super.clone();
tmp.m = (Money)this.m.clone();
return tmp;
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Student1 student1 = new Student1();
Student1 student2 = (Student1)student1.clone();
System.out.println(student1.m.money);
System.out.println(student2.m.money);
System.out.println("==================");
student2.m.money = 25.5;
System.out.println(student1.m.money);
System.out.println(student2.m.money);
}
}
//输出结果
//18.8
//18.8
//==================
//18.8
//25.5
由此代码的实现我们可以对深拷贝有一个理解