最近看一些书籍,深拷贝和浅拷贝的字样,总是浮现在眼前,于是乎整理了一下,关于java的深浅拷贝原理和实现。
1. 什么是深/浅拷贝?
浅拷贝:对目标对象的基本数据类型值的复制和引用类型的地址的复制;
深拷贝:对目标对象的基本数据类型值的复制以及应用类型值复制(专业点称之为动态内存)。
从概念上分很难以理解,下图列出了两者的区别:
1)浅拷贝
上图中,左侧是原始对象(基本数据类型、引用类型),但使用浅拷贝方式生成一个新对象,使得新对象的基本类型数值与原始对象一致,但是引用数据类型会指向原始对象引用类型,因此当原始对象和浅拷贝对象任何一方修改了引用类型的值,那么另一方也会发生改变。因为两者指向同一个对象。
2)深拷贝
从上图可以发现原始对象和深拷贝对象两者没用引用连接关系。深拷贝实际执行的是生成一个新的对象,基本数据类型与原始对象一直,引用数据类型通过原始对象引用数据类型值构造的新对象。通俗点说就是深拷贝对象的引用数据与原始对象的引用数据值相同,但不是同一个对象,不指向同一块地址。
2. java实现深/拷贝
3. 深/浅拷贝的差异
从2中代码实现,可以发现深拷贝是重新构造对象的过程,因此效率并不是很好。而浅拷贝由于拷贝对象与原始对象之间引用对象是共享的,因此容易导致任意一方修改引用类型属性,而另一方也修改了,容易导致错误的发生。
一般而言,如果原始对象变量多为基本数据类型,且引用类型不常修改,建议使用浅拷贝;反之建议使用深拷贝。