Kotlin中如何复制对象至新对象且不修改原对象?
解决Kotlin中对象复制不影响原对象的问题
你碰到的这个问题,本质是引用类型的赋值逻辑导致的——当你执行header2 = header1时,并没有生成一个新的Record对象,只是让header2和header1指向内存中同一个实例。所以不管修改哪个变量的属性,本质都是在操作同一个对象,自然会互相影响。
下面给你几种实用的解决方案,根据你的场景选就行:
1. 利用Data Class的copy()方法(推荐!)
如果你的Record是用data class定义的,Kotlin会自动为它生成一个copy()函数,能快速创建对象的浅拷贝:
// 假设你的Record是这样的data class data class Record(var name: String) var header1: Record? = Record("old_name") var header2: Record? = null // 用copy()创建新对象,而不是直接赋值引用 header2 = header1?.copy() header2?.name = "new_name" // 此时header1的name还是"old_name",header2是"new_name",完全独立
⚠️ 注意:copy()默认是浅拷贝——如果Record里包含其他引用类型的属性(比如另一个自定义类),嵌套的对象仍然是共享引用。这种情况需要做深拷贝,后面会讲。
2. 手动创建新对象并复制属性
如果Record不是data class,或者你需要更精细的控制,可以手动实例化新对象,把原对象的属性一个个传进去:
// 普通类的情况 class Record(var name: String) var header1: Record? = Record("old_name") var header2: Record? = null // 手动创建新对象,复制原对象的属性 header2 = header1?.let { Record(it.name) } header2?.name = "new_name"
这种方法适合属性不多的场景,虽然麻烦但直观。
3. 自定义深拷贝(处理嵌套引用类型)
如果Record里有嵌套的引用类型属性(比如Address类),浅拷贝会导致嵌套对象仍然共享,这时候需要自定义深拷贝逻辑:
data class Address(var street: String) data class Record(var name: String, var address: Address) // 给Record添加深拷贝方法 fun Record.deepCopy(): Record { return this.copy( address = this.address.copy() // 同时复制嵌套的Address对象 ) } // 使用深拷贝 var header1 = Record("old_name", Address("Main Street")) var header2 = header1.deepCopy() header2.address.street = "New Street" // header1的address.street还是"Main Street",不受影响
如果嵌套层级更深,需要逐层复制所有引用类型的属性,确保每个层级都是新对象。
总结
- 简单的data class直接用默认的
copy(),满足绝大多数浅拷贝场景; - 普通类手动创建新对象复制属性;
- 有嵌套引用类型时,自定义深拷贝方法确保完全独立。
内容的提问来源于stack exchange,提问作者SadeQ digitALLife
相关产品推荐
相关产品推荐

