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

如何解决Kotlin数据类属性映射过程中出现的StackOverflowError问题

问题根本原因

你在Kotlin属性的自定义getter实现中直接访问了属性本身,触发了无限递归调用getter方法,最终导致栈溢出。

两处具体错误点

  1. contactPoints属性的get方法逻辑中,代码contactPoints.addresses = addressList会触发再次调用getContactPoints(),形成死循环,全程没有创建实际的ContactPoints实例,一直在递归调用getter。
  2. mainSubscriber属性的get方法存在完全相同的问题:mainSubscriber.firstName = givenName直接访问属性本身,再次触发getter调用,形成死循环。

修复方案

在自定义getter中先创建对应类的实例,对实例进行赋值操作后再返回实例,不要直接访问属性本身,修复后的UserInfoResponse对应代码如下:

data class UserInfoResponse(
        val id: String,
        val accountType: String,
        val alternatePhone: String,
        val alternatePhoneType: String,
        val billingCity: String,
        val billingCountry: String,
        val billingId: String,
        val billingPostalAddress1: String,
        val billingPostalAddress2: String,
        val billingPostalCode: String,
        val billingStateProvince: String,
        val currency: String,
        val effectiveRoles: List<EffectiveRole>,
        val givenName: String,
        val mailingCity: String,
        val mailingCountry: String,
        val mailingPostalAddress1: String,
        val mailingPostalAddress2: String,
        val mailingPostalCode: String,
        val mailingStateProvince: String,
        val primaryPhone: String,
        val primaryPhoneType: String,
        val secondaryPhone: String,
        val secondaryPhoneType: String,
        val suffix: String,
        val surname: String,
        val userName: String,
        val vehicles: List<Vehicle>,
) {
        val contactPoints: ContactPoints
                get() = run {
                        // 先创建ContactPoints实例
                        val points = ContactPoints()
                        var address = Address()
                        val addressList = arrayListOf<Address>()
                        address.id = id
                        address.street = billingPostalAddress1
                        address.addressLine1 = billingPostalAddress1
                        address.city = billingCity
                        address.state = billingStateProvince
                        address.postalCode = billingPostalCode
                        address.country = billingCountry
                        addressList.add(address)
                        address = Address()
                        address.id = id
                        address.street = mailingPostalAddress1
                        address.city = mailingCity
                        address.state = mailingStateProvince
                        address.postalCode = billingPostalCode
                        address.country = mailingCountry
                        addressList.add(address)
                        // 对实例赋值而非直接访问属性
                        points.addresses = addressList

                        var phone = Phone()
                        val phoneList = arrayListOf<Phone>()
                        phone.value = primaryPhone
                        phoneList.add(phone)
                        phone = Phone()
                        phone.value = primaryPhone
                        phoneList.add(phone)
                        points.phones = phoneList
                        // 返回实例
                        points
                }

        val mainSubscriber: MainSubscriber
                get() = run {
                        // 先创建MainSubscriber实例
                        val subscriber = MainSubscriber()
                        subscriber.firstName = givenName
                        subscriber.lastName = surname
                        subscriber.contactPoints = contactPoints
                        // 返回实例
                        subscriber
                }
}

可选优化

如果你不需要每次访问属性都重新生成新的实例,可以去掉自定义getter,直接在初始化时赋值,仅生成一次实例,性能更好:

val contactPoints: ContactPoints = run {
    // 逻辑和上面getter内的完全一致
}

val mainSubscriber: MainSubscriber = run {
    // 逻辑和上面getter内的完全一致
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:54:03