Kotlin中Any类型多态序列化问题:如何处理Object类型value?
处理Kotlin序列化中动态类型Value的对象类型场景
步骤1:定义对应Object类型的序列化数据类
针对API返回的Object类型value(比如示例中的hsv结构),先创建带@Serializable注解的数据类:
@Serializable data class HsvValue( val h: Int, val s: Int, val v: Int )
如果还有其他Object类型的value,按同样方式定义对应的序列化数据类即可。
步骤2:扩展序列化器的类型映射表
修改dataTypeSerializers,将每个instance字符串与对应的类型序列化器关联,覆盖基础类型和自定义对象类型:
private val dataTypeSerializers: Map<String, KSerializer<Any>> = mapOf( // 基础类型映射 "rgb" to Int.serializer(), "bool" to Boolean.serializer(), "text" to String.serializer(), // 对象类型映射 "hsv" to HsvValue.serializer() ).mapValues { (_, serializer) -> serializer as KSerializer<Any> }
步骤3:优化反序列化逻辑(可选但推荐)
原代码的decodeSequentially分支可能存在先解析value再解析instance的风险,调整为循环解析确保先拿到instance再处理value:
override fun deserialize(decoder: Decoder): StateObject = decoder.decodeStructure(descriptor) { var instance: String? = null var value: Any? = null while (true) { when (val index = decodeElementIndex(descriptor)) { 0 -> instance = decodeStringElement(descriptor, index) 1 -> { val serializer = getValueSerializer(instance ?: throw SerializationException("Instance字段必须先于Value解析")) value = decodeSerializableElement(descriptor, index, serializer) } CompositeDecoder.DECODE_DONE -> break else -> error("Unexpected index: $index") } } StateObject( instance ?: throw SerializationException("Instance字段缺失"), value ?: throw SerializationException("Value字段缺失") ) }
完整修改后的代码
@Serializable(with = StateSerializer::class) data class StateObject( val instance: String, val value: Any ) // 对应hsv类型的序列化数据类 @Serializable data class HsvValue( val h: Int, val s: Int, val v: Int ) object StateSerializer : KSerializer<StateObject> { private val dataTypeSerializers: Map<String, KSerializer<Any>> = mapOf( "rgb" to Int.serializer(), "bool" to Boolean.serializer(), "text" to String.serializer(), "hsv" to HsvValue.serializer() ).mapValues { (_, serializer) -> serializer as KSerializer<Any> } private fun getValueSerializer(instance: String): KSerializer<Any> = dataTypeSerializers[instance] ?: throw SerializationException("不支持的instance类型: $instance") override val descriptor: SerialDescriptor = buildClassSerialDescriptor("StateObject") { element("instance", serialDescriptor<String>()) element("value", buildClassSerialDescriptor("Any")) } override fun deserialize(decoder: Decoder): StateObject = decoder.decodeStructure(descriptor) { var instance: String? = null var value: Any? = null while (true) { when (val index = decodeElementIndex(descriptor)) { 0 -> instance = decodeStringElement(descriptor, index) 1 -> { val serializer = getValueSerializer(instance ?: throw SerializationException("Instance字段必须先于Value解析")) value = decodeSerializableElement(descriptor, index, serializer) } CompositeDecoder.DECODE_DONE -> break else -> error("Unexpected index: $index") } } StateObject( instance ?: throw SerializationException("Instance字段缺失"), value ?: throw SerializationException("Value字段缺失") ) } override fun serialize(encoder: Encoder, value: StateObject) { encoder.encodeStructure(descriptor) { encodeStringElement(descriptor, 0, value.instance) val serializer = getValueSerializer(value.instance) encodeSerializableElement(descriptor, 1, serializer, value.value) } } }
使用示例
反序列化后可通过类型转换获取具体的value类型:
val state: StateObject = // 从API反序列化得到的对象 when (state.instance) { "hsv" -> { val hsvValue = state.value as HsvValue // 处理HSV逻辑 } "rgb" -> { val rgbValue = state.value as Int // 处理RGB逻辑 } // 其他类型分支 }
内容的提问来源于stack exchange,提问作者pie
相关产品推荐
相关产品推荐

