来自:https://zhuanlan.zhihu.com/p/30320149
JAVA对象拷贝分为两种方式,一种是引用拷贝,一种是对象拷贝
引用拷贝:和对象拷贝的不同之处在于,引用拷贝只会生成一个新的对象引用地址,但两个地址其最终指向的还是同一个对象;
对象拷贝:这种方式会重新生成一个新的对象,生成的新对象与原来的对象没有任何关联。
1、引用拷贝(对象赋值)
- 1)引用拷贝也就是我们常用的对象赋值,这种方式不会生成新的对象,只会在原对象上增加了一个新的对象引用,两个引用指向的对象还是是同一个;
- 2)引用拷贝的问题:因为user1和user2其实指向的是同一个对象,所以当我们修改user2的属性时其实修改的也是user1这个对象。
2、对象浅拷贝
-1) 浅拷贝的结果是:重新生成一个新的对象,新的对象和原来的对象是没有任何关系的,但是如果对象中的某个属性是引用类型的话,那么该属性对应的对象是不会重新生成的,浅拷贝只会重新拷贝当前的对象,并不会重新生成其属性引用的对象。
- 2)实现浅拷贝 :实现 Cloneable 接口 并重写clone 方法
我们可以看出结论:
(1)user2修改了name之后并没有影响user1的name,这说明user2和user1对象是独立的。
(2)user2修改了teacher
对象属性之后user1的teacher对象属性也同时改变了,这说明对象的clone方法并不会把其对象中引用的其他对象进行拷贝,这也是我们俗称的浅拷贝。
- 3)为什么浅拷贝不会拷贝其引用的对象?
也许你也有个疑问,为什么clone的方式不能把其引用的对象也重新生成一份,那多省事情,我想应该有以下几个原因;
1、不给其他类强加意义
这个就好比,User类为了能进行浅拷贝就实现了Cloneable 接口,但是其引用对象Teacher没有实现Cloneable
也许说明他本身就不想被拷贝,如果在拷贝User的情况下,同时也把Teacher拷贝了,这不就等于干了一件没有遵循他人同意的事,干了之后人家还不知道,傻傻的以为没人可以通过clone来拷贝出另外一个Teacher。2、不破坏其原来对象的代码逻辑
如果User引用的Teacher 是个单例模式的对象,那如果在User拷贝的时候同时也拷贝出了一个Teacher
那是不是就会破坏Teacher这个单例模式对象的逻辑初衷。
3、对象深拷贝
- 1)深拷贝相比浅拷贝的不同就是,深拷贝会把拷贝的对象和其属性引用的对象都重新生成新的对象。
- 2)如何实现深拷贝
如果想要深拷贝一个对象,这个对象必须要实现Cloneable接口,重写clone方法。并且在clone方法内部,把该对象引用的其他对象也要clone一份 ,这就要求这个被引用的对象必须也要实现Cloneable接口并且实现clone方法。、