深拷贝与浅拷贝的问题,也是面试中的常客。虽然大家都知道两者表现形式不同点在哪里,但是很少去深究其底层原理,也不知道怎么才能优雅的实现一个深拷贝。其实工作中也常常需要实现深拷贝,今天一灯就带大家一块深入剖析一下深拷贝与浅拷贝的实现原理,并手把手教你怎么优雅的实现深拷贝。,浅拷贝: 只拷贝栈内存中的数据,不拷贝堆内存中数据。,深拷贝: 既拷贝栈内存中的数据,又拷贝堆内存中的数据。,由于浅拷贝只拷贝了栈内存中数据,栈内存中存储的都是基本数据类型,堆内存中存储了数组、引用数据类型等。,
,使用代码验证一下:,想要实现clone功能,需要实现 Cloneable 接口,并重写 clone 方法。,输出结果:,从结果中可以看出,对象拷贝把name修改为”张三“,原对象并没有变,name是String类型,是基本数据类型,存储在栈内存中。对象拷贝了一份新的栈内存数据,修改并不会影响原对象。,然后对象拷贝把Job中content修改为”测试“,原对象也跟着变了,原因是Job是引用类型,存储在堆内存中。对象拷贝和原对象指向的同一个堆内存的地址,所以修改会影响到原对象。,深拷贝是既拷贝栈内存中的数据,又拷贝堆内存中的数据。,
,实现深拷贝有很多种方法,下面就详细讲解一下,看使用哪种方式更方便快捷。,通过实现Cloneable接口来实现深拷贝是最常见的。,想要实现clone功能,需要实现**Cloneable接口,并重写clone**方法。,输出结果:,从结果中可以看出,user拷贝对象修改了name属性和Job对象中内容,都没有影响到原对象,实现了深拷贝。,通过实现Cloneable接口的方式来实现深拷贝,是Java中最常见的实现方式。,缺点是: 比较麻烦,需要所有实体类都实现Cloneable接口,并重写clone方法。如果实体类中新增了一个引用对象类型的属性,还需要添加到clone方法中。如果继任者忘了修改clone方法,相当于挖了一个坑。,实现方式就是:,这是个偏方,但是偏方治大病,使用起来非常方便,一行代码即可实现。,下面使用fastjson实现,使用Gson、Jackson也是一样的:,输出结果:,从结果中可以看出,user拷贝对象修改了name属性和Job对象中内容,并没有影响到原对象,实现了深拷贝。,再说一下Java集合怎么实现深拷贝?,其实非常简单,只需要初始化新对象的时候,把原对象传入到新对象的构造方法中即可。,以最常用的ArrayList为例:,
© 版权声明
文章版权归作者所有,未经允许请勿转载。