先上通过 clone 深拷贝的使用步骤:
model 先实现 Cloneable, 重写 clone 方法.model 调用 clone 就会生成一个 全新的对象.new 一个新数组 copyList, 遍历 原始数组 oriList, 一个一个添加到 copyList 即可.talk is cheap, show me the code:
class MainKotlin {
@Test
fun test0() {
val oriList = ArrayList()
val model0 = Model(0, "name0")
val model1 = Model(1, "name1")
val model2 = Model(2, "name2")
oriList.add(model0)
oriList.add(model1)
oriList.add(model2)
val copyList = ArrayList()
oriList.forEach {
copyList.add(it.clone())
}
println("list = $oriList")
println("copyList = $copyList")
println("======== change name ========")
model0.name = "name0 changed"
println("list = $oriList")
println("copyList = $copyList")
}
class Model(): Cloneable {
var id: Int? = null
var name: String? = null
constructor(id: Int, name: String) : this() {
this.id = id
this.name = name
}
// 添加 try catch, 防止奇怪的异常
public override fun clone(): Model {
return try {
return super.clone() as? Model ?: Model()
} catch (e: CloneNotSupportedException) {
Model()
}
}
override fun toString(): String {
return "Model(id=$id, name=$name)"
}
}
}
输出结果:
可以看到 model0 更改 name 时, list 随之改变, copyList 没有改变, 成功~
起因:
今天在做单例的时候, 被数据的一些状态整懵了, 虽然想到了可以通过深拷贝解决问题, 但竟然直接使用了 newList.addAll(oldList) ... 结果又排查问题查了半天...才想到 list 中的 model 也是要完全 new 出来才行, model 里面那么多属性, 一个一个赋值太不优雅啦, 在网上查了下可以通过:
clone 解决实现序列化, 通过反序列化 new 出来对象但序列化整了半天没成功, 就换 clone, 有空再看下序列化怎么整...
注意:
java的一个类,如果要使用 Cloneable 实现拷贝功能, 需要先实现这个接口, 然后重写Object的clone方法. 对于类中的引用类型的属性, 需要在clone方法中实现深拷贝, 否则就是浅拷贝.
属性中有引用对象的话, 引用对象也要实现 Cloneable, 然后这个引用对象也要调用 clone 方法才行...有点麻烦, 得封装一下才好用...后续带封装...
后续待优化:
可以把 集合 的深拷贝封装一个函数, 这样调用起来比较方便, 待执行任务...
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)