一个工作了5年的程序员私信我说,前几天去阿里面试被问到这样一个这样的面试题,说谈谈你对深克隆和浅克隆的理解。他回答说深克隆是克隆值,浅克隆是克隆引用,当时他只说了这样一句话,回答完以后,他看到面试官的表情很诧异,面试也没有继续深入追问了。小伙伴们,如果是你来回答,你也会这样回回答吗?
这位小伙伴的回答并没有错,只是面试官觉得回答得有点抽象而已。今天,我给大家详细聊一聊。
另外,我花了1个多星期把往期的面试题解析配套文档准备好了,想获取的小伙伴可以在我的煮叶简介中找到。
说到克隆啊,我还不得不说到一个设计模式,原型模式。先来看原型模式的定义。
1、原型模式定义
原型模式的官方原文是这样的:
大致意思是,指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。其实复制、克隆、拷贝表达的都是同一个意思。因为Java中的数据类型分为引用类型和值类型,因此,在克隆数据的过程中,就有了深克隆和浅克隆。
2、深克隆和浅克隆
那么,深克隆和浅克隆的本质区别又是什么呢?我归纳为以下两点:
第1点:看数据拷贝后两者之间是否有关联。
第2点:改变一个值是否会影响到另一个值变化。
那么,到底什么是深克隆,什么是浅克隆呢?
先来看浅克隆,浅克隆就是数据拷贝后,一方数据变化另一方会跟着变化。
如图所示:有原型对象Object,它是引用类型,然后拷贝后产生两个克隆对象obj1和obj2,只是它们克隆的是Object的内存地址,因此ob1和obj2都指向Object,那么Object中的成员变量值发生改变时,obj1和obj2指向的成员变量值也就会发生改变。
实现浅克隆的常用API有以下3种,
1、工具类BeanUtils和PropertyUtils,BeanUtils是Spring提供的,PropertyUtils是Apache的commons包中提供的。
2、实现Clonenable接口
3、Arrays的copyOf()方法
下面来看深克隆,深克隆就是数据拷贝后,原型对象和克隆对象之间没有关联。如图所示:obj1和obj2分别指向不同的原型对象,拷贝的是值不是内存地址。
深克隆常用的API有以下5种:
1、重写clone()方法
2、序列化
3、Apache commons工具包中的SerializationUtils的clone()方法
4、JSON工具类
5、通过构造方法手动new对象。
以上就是我对浅克隆和深克隆的理解。