You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:15:47