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

Kotlin如何实现可观察且支持序列化的多平台兼容属性?

问题根源说明

Kotlinx Serialization 默认会忽略委托属性,因为委托属性的实际值存储在委托类的实例中,而非当前VO类的直接字段,序列化器默认不会通过getter/setter访问属性值,因此会出现序列化结果为空的情况。


可行解决方案(按优先级排序)

方案1:委托属性加@SerialName显式标注(最易实现,全平台兼容)

不需要修改现有委托逻辑,只需要给需要序列化的委托属性加上@SerialName注解,显式告诉序列化器要处理这个属性,序列化器会自动通过getter取值、setter设值,完全兼容JVM、JS、Android、Native全平台。
示例代码:

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json
import kotlinx.serialization.encodeToString
import kotlin.reflect.KProperty

interface Observable {
    fun change(message: String) {
        println("changing $message")
    }

    @Suppress("ClassName")
    class default<T>(defaultValue: T) {
        private var value: T = defaultValue
        operator fun getValue(observable: Observable, property: KProperty<*>): T = value
        operator fun setValue(observable: Observable, property: KProperty<*>, value: T) {
            this.value = value
            observable.change(property.name)
        }
    }
}

@Serializable
class BlahVO : Observable {
    // 加@SerialName显式指定序列化字段名即可正常序列化
    @SerialName("value1")
    var value1: String by Observable.default("value1")

    fun toJson(): String = Json.encodeToString(serializer(), this)
}

测试执行输出和手动写setter的效果完全一致:

changing value1
{"value1":"test2"}

如果不需要反序列化时触发变更监听,可以加个简单的开关控制:

interface Observable {
    var isDeserializing: Boolean
    fun change(message: String) {
        if (!isDeserializing) println("changing $message")
    }
}

反序列化时把isDeserializing设为true,结束后恢复为false即可。


方案2:KSP生成样板代码(性能最优,无运行时开销)

如果属性数量多,不想每个都加注解,可以自定义轻量的KSP(Kotlin符号处理)注解处理器,编译期自动给标注了自定义注解的属性生成带变更监听的setter,生成的代码和你手动写的完全一致,没有任何运行时开销,也完全兼容序列化。
实现步骤:

  1. 定义源码级注解:
@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
annotation class Watchable
  1. 实现KSP处理器,遍历所有标注了@Watchable的属性,自动生成带change(property.name)调用的setter逻辑
  2. 业务代码写法极简:
@Serializable
class BlahVO : Observable {
    @Watchable
    var value1: String = ""
}

内容的提问来源于stack exchange,提问作者Jan Vladimir Mostert

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 06:45:02