Skip to content

Kotlinx Serialization 实战

源:Kotlin 序列化官方指南

kotlinx.serialization 是 Kotlin 官方推荐的序列化方案。与 Gson/Jackson 不同,它采用 编译器插件 + 运行时库 的架构,生成静态序列化代码,实现了 零反射 (Zero-Reflection)高性能,且完美支持 KMP (跨平台)

快速配置

kotlin
[plugins]
# 确保版本与 Kotlin 版本匹配
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }

[libraries]
kotlinx-serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.6.3" }
kotlin
plugins {
    alias(libs.plugins.kotlin.serialization)
}

dependencies {
    implementation(libs.kotlinx.serialization.json)
}

核心用法

只需添加 @Serializable 注解,编译器自动生成序列化逻辑。

kotlin
@Serializable
data class User(
    val name: String,
    val age: Int = 18, // 只有设置了默认值,encodeDefaults 配置才生效
    @SerialName("is_active") val isActive: Boolean, // 自定义 JSON 键名
    @Transient val tempState: String = "" // 不参与序列化
)

// 序列化
val jsonString = Json.encodeToString(User("Bruce", isActive = true))

// 反序列化
val user = Json.decodeFromString<User>(jsonString)

Json 全局配置最佳实践

建议创建一个全局单例 Json 实例,复用配置。

kotlin
val AppJson = Json {
    // 忽略 JSON 中存在但 DataClass 中不存在的字段 (极重要,防止后端加字段导致崩溃)
    ignoreUnknownKeys = true 
    
    // 宽松模式:允许键名不带引号、允许 NaN 等非标 JSON
    isLenient = true
    
    // 序列化时,如果字段值等于默认值,也强制写入 JSON
    encodeDefaults = true
    
    // 格式化输出 (仅用于调试,生产环境建议关闭以减小体积)
    prettyPrint = false
    
    // 强制非空性:如果 JSON 字段缺失且无默认值,设为 false 会报错
    explicitNulls = false
}

处理多态 (Polymorphism)

处理 sealed class 时,库会自动根据 type 字段(默认)识别子类。

kotlin
@Serializable
sealed class Message {
    @Serializable 
    @SerialName("text") // 指定 type 字段的值为 "text"
    data class Text(val content: String) : Message()

    @Serializable 
    @SerialName("img")
    data class Image(val url: String) : Message()
}

// JSON: { "type": "text", "content": "Hello" }
// 自动反序列化为 Message.Text

R8 / ProGuard 混淆配置

虽然该库不依赖反射,但它依赖自动生成的 Serializer 类。如果是 Android 项目,通常无需手动配置,因为库自带了 Consumer ProGuard 规则。

如果遇到问题,确保保留以下规则:

proguard
-keepattributes *Annotation*, InnerClasses
-dontobfuscate

(注:通常仅在极度严格的混淆设置下才需要手动干预)

泛型序列化

序列化泛型类时,编译器需要知道泛型参数的 Serializer。

kotlin
@Serializable
data class Response<T>(val data: T)

// 简单类型:库自动推导
val resp = Response("OK")
Json.encodeToString(resp)

// 复杂泛型:有时需显式传 Serializer (极少见,compile-time 也就绪)