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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 14:55:15