在学习java基础的时候,大家应该都听过,有一种创建对象的方式,叫clone。
clone其实就是顾名思义,“克隆”,克隆一个一模一样的对象。
在学习深浅拷贝的时候,按概念来,clone是浅拷贝,但其实,
clone并不是真正的浅拷贝,或者说并不是在任何时候都是浅拷贝。
如下这个试验可以证明这一点:
@SneakyThrows
@Test
public void test02(){
// clone的方式 浅拷贝 本质是克隆出来的对象与源对象共用一块内存
CloneMe cloneMe = new CloneMe();
cloneMe.setAge("13");
cloneMe.setName("xiaoming");
CloneMe meClone = (CloneMe)cloneMe.clone();
System.out.println("clone对象" + meClone.getAge());
meClone.setAge("14");
System.out.println("改变clone对象后,克隆对象:" + meClone.getAge());
System.out.println("改变clone对象后,源对象:" + cloneMe.getAge());
System.out.println("克隆对象的地址:" + meClone);
System.out.println("源对象的地址:" + cloneMe);
// 结论 此处其实是深拷贝了
}
@SneakyThrows
@Test
public void test03(){
// clone的方式 对象内部存一个对象 (非基本数据类型)
CloneMe cloneMe = new CloneMe();
People people = new People();
people.setName("xiaoming");
cloneMe.setPeople(people);
CloneMe meClone = (CloneMe)cloneMe.clone();
meClone.getPeople().setName("xiaohong");
System.out.println("改变clone对象后,克隆对象:" + meClone.getPeople().getName());
System.out.println("改变clone对象后,源对象:" + cloneMe.getPeople().getName());
System.out.println("克隆对象的地址:" + meClone);
System.out.println("源对象的地址:" + cloneMe);
System.out.println("克隆对象内部对象的地址:" + meClone.getPeople());
System.out.println("源对象内部对象的地址:" + cloneMe.getPeople());
// 结论 此处就是浅拷贝了
// 内部对象People实现cloneable接口 也没用
// 结论 clone是浅拷贝 只是在clone对象内部属性是非基本数据类型(对象)时,
// 当内部都是基本数据类型时,clone其实也是深拷贝
}
结论:
当对象内部全是基本数据类型时,clone方式其实是深拷贝,clone对象内部属性的修改并不会影响源对象。
但是当对象内部含有包装类型时,clone方式就是浅拷贝了,内部包装类的修改会影响源对象。