在Kotlin中,data数据类默认的copy方法实现的是浅拷贝,但我们有时候需要实现深拷贝。 在kotlin中,实现就比较容易了。
那么什么是深拷贝与浅拷贝呢?
简单理解,浅拷贝指的是如果要拷贝A对象,则会重新创建一个B对象,并将其内部变量全部赋值给B对象,所以我们称之为浅拷贝。
深拷贝指的是:拷贝后,如果B对象中存在引用对象,此时更改这个引用对象不会影响到原有A对象中的引用对象,因为它两所操作的内存并不是同一块内存。而浅拷贝则相反,当你操作B对象中的某个引用对象时,就会影响到A对象。对于基本类型,深拷贝与浅拷贝都是直接赋值,并没有什么区别。
代码如下:
fun <T : Any> T.deepCopy(): T { //如果不是数据类,直接返回 if (!this::class.isData) { return this } //拿到构造函数 return this::class.primaryConstructor!!.let { primaryConstructor -> primaryConstructor.parameters.map { parameter -> //转换类型 //memberProperties 返回非扩展属性中的第一个并将构造函数赋值给其 //最终value=第一个参数类型的对象 val value = (this::class as KClass<T>).memberProperties.first { it.name == parameter.name }.get(this) //如果当前类(这里的当前类指的是参数对应的类型,比如说这里如果非基本类型时)是数据类 if ((parameter.type.classifier as? KClass<*>)?.isData == true) { parameter to value?.deepCopy() } else { parameter to value } //最终返回一个新的映射map,即返回一个属性值重新组合的map,并调用callBy返回指定的对象 }.toMap().let(primaryConstructor::callBy) } } data class A(val name: String) data class Dep(val a: A) fun main() { val dep = Dep(A("123")) val copyDep = dep.copy() val deepCopy = dep.deepCopy() println(dep === copyDep) println(dep === deepCopy) println(dep.a === copyDep.a) println(dep.a === deepCopy.a) }
运行结果: