1.创建对象的方法(目前读者就学到2个,以后学到更多会来补充的): (1)new (2)clone()方法 我们发现这个clone()方法标红了,转到源码一看(ctrl+b) 发现 clone()方法的返回值是Object类型,于是我们进行强制类型转换
转换完后,发现还是错的,为什么呢?
clone()方法是Object类的方法,所有类都继承Object类,按理说这样调用clone()方法是没有问题的:
但是:调用clone()方法的类必须实现Cloneable接口,重写clone方法,并声明错误
我们发现,重写的clone方法,实际上并没有真正重写,他还是调用了父类Object的方法。。而且根据图二我们也看到clone()方法并没有写具体的实现,因为clone()方法是底层的c/c++写的,所以我们就算重写,也是调用父类的clone方法
可见,他确实是拷贝了一份Person对象
这时候,我们可以说clone()方法实现了深拷贝吗? - 不可以!
深拷贝/浅拷贝 : 要看代码的写法+拷贝的数据类型(拷贝啥 咋拷贝) 这里目前看是深拷贝。
但是如果稍微变一变,他就是浅拷贝了
class Money{
public double m=12.5;
}
class Person implements Cloneable{
public int age;
public Money money=new Money();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class TestDemo2 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1=new Person();
//Person person2=person1.clone(); //报错 不兼容的类型: java.lang.Object无法转换为Person
//object类型是所有类型的父类,要强制类型转换发生向下转型
Person person2=(Person)person1.clone();
person1和person2的money的地址都是一样,可见指向了同一块空间
此时,他就不再是深拷贝,他的内存布局是这样的
这个m由person1和person2共同指向 ,如果通过person1修改了m,那么通过person2找到的m也被修改了
所以:如果这样,我们又要说这是浅拷贝了
可见:我们只是克隆了Person对象,并没有克隆Money对象。所以不能说某个方法实现了深/浅拷贝。要看具体是怎么实现的
现在,我要把它变成深拷贝。把它的Money对象也去克隆一份出来
可见:他们money指向的对象是不同的,也就实现了这种情况的深拷贝
此时,他的内存分布图:
代码展示
class Money implements Cloneable{
public double m=12.5;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public int age;
public Money money=new Money();
@Override
protected Object clone() throws CloneNotSupportedException { //是在这里调用了clone()方法,所以实现相对的深拷贝也要在这里修改
//return super.clone(); //使Person拷贝了一份
Person tmp=(Person)super.clone(); //这个代码和上面那个代码是一样
//return super.clone() - 这个return就相当于return tmp
//但是现在我要实现深拷贝,所以我要把这个tmp写出来
tmp.money=(Money) this.money.clone();//所以Money这个类也必须实现Cloneable接口
return tmp;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class TestDemo2 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1=new Person();
//Person person2=person1.clone(); //报错 不兼容的类型: java.lang.Object无法转换为Person
//object类型是所有类型的父类,要强制类型转换发生向下转型
Person person2=(Person)person1.clone();
System.out.println(person1);
System.out.println(person2);
person1.age=99;
person2.age=100;
System.out.println(person1);
System.out.println(person2);
System.out.println(person1.money);//Money@28d93b30
System.out.println(person2.money);//Money@1b6d3586
}
}