序列化

序列化是把运行时对象转换成可传输或可存储格式的过程;反序列化则是把外部数据转换回运行时对象。JSON、Protocol Buffers、CBOR 等都是常见格式。

Kotlin 官方生态中的主要方案是 kotlinx.serialization

组成部分

kotlinx.serialization 包含:

  • Gradle 插件:org.jetbrains.kotlin.plugin.serialization
  • 编译器插件。
  • 运行时库。
  • 多种格式库,例如 JSON、CBOR、Protocol Buffers。

它不是 Kotlin 标准库的一部分,需要单独配置。

Gradle 配置

plugins {
    kotlin("jvm") version "2.4.0"
    kotlin("plugin.serialization") version "2.4.0"
}

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:<version>")
}

注意:kotlinx.serialization 库有自己的版本号,不等于 Kotlin 版本号。实际项目要查看 kotlinx.serialization 发布页选择版本。

Multiplatform 项目中通常放在 commonMain

kotlin {
    sourceSets {
        commonMain.dependencies {
            implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:<version>")
        }
    }
}

平台特定 artifact 通常由 Gradle 自动处理,不需要手动添加 JVM/JS/Native 分类。

基本 JSON 示例

import kotlinx.serialization.Serializable
import kotlinx.serialization.json.Json

@Serializable
data class User(
    val id: Long,
    val name: String
)

fun main() {
    val json = Json.encodeToString(User(1, "Ada"))
    val user = Json.decodeFromString<User>(json)
    println(user)
}

@Serializable 让编译器插件生成序列化逻辑。与 Java 反射式序列化不同,kotlinx.serialization 更依赖编译期生成。

常用 Json 配置

val json = Json {
    ignoreUnknownKeys = true
    prettyPrint = true
    encodeDefaults = true
    explicitNulls = false
}

常见含义:

  • ignoreUnknownKeys:输入 JSON 有未知字段时不失败,适合兼容服务端新增字段。
  • prettyPrint:输出格式化,适合日志或调试。
  • encodeDefaults:是否输出默认值字段。
  • explicitNulls:控制 null 字段是否显式输出。

API 通信时要和后端约定这些规则,不要让默认配置悄悄决定协议语义。

字段名映射

@Serializable
data class User(
    @SerialName("user_id")
    val userId: Long
)

Kotlin 属性通常是 camelCase,而 JSON API 可能是 snake_case。@SerialName 用于明确协议字段名。

默认值与兼容性

@Serializable
data class User(
    val id: Long,
    val name: String = "unknown"
)

如果输入缺少 name,可以使用默认值。默认值是演进协议时的重要工具,但也可能掩盖数据质量问题。核心字段不要随意给默认值。

多态序列化

密封类非常适合表达有限类型层级:

@Serializable
sealed interface Event

@Serializable
data class Login(val userId: Long) : Event

@Serializable
data class Logout(val userId: Long) : Event

多态序列化需要关注类型判别字段、注册方式和与外部协议的兼容。内部事件可以使用 Kotlin 友好的默认配置;外部公开 API 应明确字段格式。

支持格式

官方列出的格式包括:

  • JSON。
  • Protocol Buffers。
  • CBOR。
  • Properties。
  • HOCON,JVM only。

除 JSON 外,很多格式 API 可能是 Experimental。生产使用时要看稳定性和版本兼容承诺。

与 Jackson/Gson 对比

Java 生态常用 Jackson、Gson、Moshi。对比:

维度 kotlinx.serialization Jackson/Gson
Kotlin 支持 Kotlin 官方生态,编译期插件 依赖模块或反射适配
多平台 JVM/JS/Native 支持更自然 多数偏 JVM
运行机制 编译期生成为主 反射/运行时机制较多
Java 生态集成 不如 Jackson 广 Jackson 在后端生态很强

如果是纯 JVM Spring 项目,Jackson 仍是默认选择之一。如果是 KMP 或需要跨 JS/Native,共享 kotlinx.serialization 更自然。

实践建议

  • KMP 项目优先考虑 kotlinx.serialization
  • JVM 后端项目要结合框架生态评估 Jackson 与 kotlinx.serialization。
  • 外部 API 字段使用 @SerialName 明确协议。
  • 协议演进时认真设计默认值和未知字段策略。
  • 不要把内部 data class 不经设计直接暴露为长期公共协议。
  • 非 JSON 格式使用前确认 Experimental 状态。

参考

  • 官方序列化文档:https://kotlinlang.org/docs/serialization.html