Kotlinx.Serialization全局类型别名SID序列化失效问题求助
解决Kotlinx Serialization直接序列化UUID别名失败的问题
问题根源
directTypeUsage测试报错的核心原因是:typealias SID = @Serializable(with = UUIDserializer::class) UUID仅仅是编译期的类型别名,运行时变量hi的实际类型仍是UUID。而Kotlinx Serialization会依据运行时的实际类型查找序列化器,由于UUID本身未标记@Serializable,也没有全局注册的序列化器,因此抛出找不到序列化器的异常。
可行解决办法
1. 序列化时显式指定序列化器
这是最直接的临时解决方案,无需修改现有类型定义,仅在直接序列化时传入自定义序列化器:
@Test fun directTypeUsage () { val hi = randomSid() val string = Json.encodeToString(UUIDserializer, hi) println(string) }
2. 改用value class替代typealias
由于typealias无法改变运行时类型,改用@JvmInline修饰的value class包装UUID,确保运行时保留类型信息,让序列化器能正确识别:
@OptIn(ExperimentalSerializationApi::class) @Serializer(forClass = UUID::class) object UUIDserializer : KSerializer<UUID> { override fun deserialize(decoder: Decoder): UUID = UUID.fromString(decoder.decodeString()) override val descriptor: SerialDescriptor get() = PrimitiveSerialDescriptor("UUID", PrimitiveKind.STRING) override fun serialize(encoder: Encoder, value: UUID) { encoder.encodeString(value.toString()) } } @JvmInline @Serializable(with = UUIDserializer::class) value class SID(val value: UUID) fun randomSid() = SID(UUID.randomUUID()) @Serializable data class Example(val id:SID = randomSid()) class SerializeId { @Test fun nestedTypeUsage() { val example = Example() val string = Json.encodeToString(example) println(string) } @Test fun directTypeUsage () { val hi = randomSid() val string = Json.encodeToString(hi) println(string) } }
这种方式兼顾类型安全与序列化便利性,后续所有SID类型的变量都能直接序列化。
3. 全局注册UUID序列化器
在Json配置中全局注册UUID的序列化器,让所有UUID类型的序列化操作都自动使用自定义序列化器:
// 全局配置Json实例 val json = Json { serializersModule = SerializersModule { contextual(UUID::class, UUIDserializer) } } class SerializeId { @Test fun nestedTypeUsage() { val example = Example() val string = json.encodeToString(example) println(string) } @Test fun directTypeUsage () { val hi = randomSid() val string = json.encodeToString(hi) println(string) } }
该方案适合需要频繁序列化UUID的场景,一次配置即可全局生效。
内容的提问来源于stack exchange,提问作者Kyle M
相关产品推荐
相关产品推荐

