kotlinx.serialization如何为接口全局注册类型适配器无需逐类注解
解决方案
你需要为ValueInterface指定全局序列化器,绕开默认的多态序列化逻辑,即可实现和Gson全局注册TypeAdapter完全一致的效果,有两种可选方案:
方案1:接口层指定序列化器(推荐)
直接给对外暴露的ValueInterface添加序列化注解,所有使用该接口作为字段类型的类自动继承该序列化规则,无需修改任何字段、无需额外配置Json实例:
- 新增
ValueInterface专属序列化器:
// 放在内部实现模块即可,无需对外暴露 object ValueInterfaceSerializer : KSerializer<ValueInterface> { // 直接复用已经写好的ValueObject序列化逻辑 private val delegateSerializer = ValueObjectAsLong override val descriptor: SerialDescriptor = delegateSerializer.descriptor override fun serialize(encoder: Encoder, value: ValueInterface) { delegateSerializer.serialize(encoder, value as ValueObject) } override fun deserialize(decoder: Decoder): ValueInterface { return delegateSerializer.deserialize(decoder) } }
- 给
ValueInterface添加@Serializable注解绑定序列化器:
@Serializable(with = ValueInterfaceSerializer::class) interface ValueInterface { // 原有代码保持不变 fun value() : Long companion object { fun create(long: Long) = ValueObject(long) } }
修改完成后原有测试代码无需任何调整即可正常运行。
方案2:Json实例全局注册(适合接口不能加注解的场景)
如果你无法修改公共接口的代码,可以在构建Json实例时通过序列化模块全局绑定ValueInterface的序列化器:
import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.contextual // 全局共用的Json实例 val globalJson = Json { serializersModule = SerializersModule { contextual(ValueInterface::class, ValueInterfaceSerializer) } }
使用时替换原来的Json单例为你自定义的实例即可:
// 测试代码修改为使用自定义的globalJson val actualStr = globalJson.encodeToString(Box("name1",ValueInterface.create(42))) val actualObj: Box = globalJson.decodeFromString("""{"name":"name2","value":43}""")
原报错原因说明
kotlinx.serialization默认对非密封的接口/抽象类会启用多态序列化逻辑,需要提前注册所有实现类,你不需要多态能力、只有唯一实现类,所以直接指定固定序列化器即可绕过该逻辑,完全符合你隐藏内部实现、不泄露序列化细节的需求。
内容的提问来源于stack exchange,提问作者anjosc
相关产品推荐
相关产品推荐

