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

Kotlin二维数组属性返回引用致原数据被修改如何解决?

问题根因

Kotlin 中的数组属于引用类型,二维数组本质是「存储了一维数组引用」的数组。直接执行 val arr = c.someArray 时,仅复制了外层数组的内存引用,arr 和类内部的 someArray 指向堆内存中同一份数据,修改 arr 的元素本质就是在修改原始数组的内容,因此会出现原对象属性被同步改动的情况。

注意:如果直接调用数组的 clone() 或 copyOf() 方法处理二维数组,仅会完成浅拷贝——外层是新数组,但内层存储的一维数组依然是原对象的引用,修改内层元素还是会影响原始数据。

解决方法

要获取完全独立、修改不影响原属性的数组副本,需要对二维数组做深拷贝,有两种常见实现思路:

  • 调用方获取数组时手动生成深拷贝
    替换原测试代码中获取数组的逻辑,遍历每一层内层数组生成独立副本,再组装为新的二维数组:
    @Test
    fun test(){
        val c = ClassHasArray()
        // 深拷贝:遍历每个内层BooleanArray生成副本,再组装为新的外层数组
        val arr = c.someArray.map { it.clone() }.toTypedArray()
        arr[1][1] = true
        printArray(c.someArray)
    }
    
  • 类设计层面避免暴露内部数组引用
    如果不希望任何外部调用方修改类内部的数组状态,可以把原始数组设为私有,公开属性每次访问时都返回深拷贝副本,从根源上杜绝外部拿到原始引用:
    class ClassHasArray {
        // 私有真实存储,外部无法直接访问
        private val _someArray = Array(3) { BooleanArray(3) }
        // 公开属性每次返回深拷贝副本,外部修改不会影响内部数据
        val someArray: Array<BooleanArray>
            get() = _someArray.map { it.clone() }.toTypedArray()
    }
    
验证结果

使用上述任意一种深拷贝方案后,测试代码的输出将符合预期,原始数组不会被修改:

[false, false, false]
[false, false, false]
[false, false, false]

提示:所有多维数组、存储引用类型元素的数组,要生成完全独立的副本都需要做逐层深拷贝,不能直接赋值或仅拷贝最外层。

内容的提问来源于stack exchange,提问作者user8637117

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 06:01:00