kotlinx.serialization 详解:Kotlin 官方无反射序列化库
Kotlin 项目处理 JSON,过去常借 Gson、Jackson,但它们依赖反射或注解扫描,在 Kotlin/JS、Native 与混淆环境下问题不断。官方答案 Kotlin/kotlinx.serialization(kotlinx.serialization)走的是编译期路线:编译器插件为 @Serializable 类直接生成序列化代码,零反射,完整支持 JVM、JS、Native 多平台,Stable 状态稳定发布。除 JSON 外还内置 Protobuf、CBOR、Hocon、Properties 多种格式。本文从核心机制、格式支持、配置实践到进阶用法,完整拆解。
1、项目概述
kotlinx.serialization 由三部分构成:编译器插件(为可序列化类生成 visitor 代码)、核心运行时库(core 序列化 API)、格式支持库(JSON 等各格式实现)。插件版本与 Kotlin 编译器同步发布,运行时库独立版本演进——当前插件随 Kotlin 2.3.20,运行时库为 1.11.0。
基本形态与生态:
- 协议为 Apache-2.0,JetBrains 官方项目,Kotlin Stable 稳定徽章
- 多平台:JVM、JS、Native 全覆盖,common 源集一份依赖即可
- 格式:JSON、Protobuf、CBOR、Hocon、Properties 五种开箱
- 社区:Kotlin Slack #serialization 频道,构建状态 TeamCity 公开
2、四大核心能力
kotlinx.serialization 的能力可以归成四根支柱。
四根支柱:
- 编译期生成:@Serializable 类的序列化器在编译时生成,无反射无扫描
- 多平台一致:同一套 API 跑在 JVM、JS、Native,KMP 项目零适配
- 多格式:五种官方格式,第三方还可扩展自定义格式
- 标准集合支持:List、Map 等标准集合与可空类型原生可序列化
能力要点:
1. 性能与 R8 兼容俱佳:无反射意味着混淆后依然工作
2. core 与格式库分离:只要 API 不要格式时引 core 即可
3. 编译器插件随 Kotlin 版本走,升级 Kotlin 无版本纠结
3、快速上手:Gradle 两步配置
配置只需两件事:加序列化插件、加库依赖。
// build.gradle.kts —— 第一步:插件与 Kotlin 版本同步
plugins {
kotlin("jvm") version "2.3.20" // 或 kotlin("multiplatform")
kotlin("plugin.serialization") version "2.3.20"
}
// 第二步:运行时库(版本独立于插件)
repositories { mavenCentral() }
dependencies {
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0")
}配置要点:
1. 插件版本必须与 Kotlin 编译器版本一致;1.4.0 以下 Kotlin 不受支持
2. KMP 项目把依赖加进 commonMain,平台源集自动解析
3. Maven 项目需在 kotlin-maven-plugin 配置 compilerPlugins
4. Bazel 用户参考 rules_kotlin 仓库的 serialization 示例
4、基础用法:序列化与反序列化
标注 @Serializable,一行完成对象与 JSON 字符串互转。
import kotlinx.serialization.*
import kotlinx.serialization.json.*
@Serializable
data class Project(val name: String, val language: String)
fun main() {
val data = Project("kotlinx.serialization", "Kotlin")
// 序列化:对象 -> JSON 字符串
val string = Json.encodeToString(data)
println(string)
// {"name":"kotlinx.serialization","language":"Kotlin"}
// 反序列化:JSON 字符串 -> 对象
val obj = Json.decodeFromString<Project>(string)
println(obj)
// Project(name=kotlinx.serialization, language=Kotlin)
}用法要点:
1. data class 加 @Serializable 即可,主构造器属性参与序列化
2. encodeToString / decodeFromString 是 JSON 场景最常用入口
3. 嵌套类、集合、可空字段开箱即用
4. 泛型反序列化由编译器推断,无需传 Class 对象
5、JSON 进阶配置
真实接口的字段命名、缺省值、宽松解析,都靠 Json 配置解决。
val json = Json {
ignoreUnknownKeys = true // 忽略未知字段,对接外部 API 必备
isLenient = true // 宽松模式:无引号数字等容错
encodeDefaults = true // 输出默认值字段
coerceInputValues = true // 非法枚举值回退为默认值
prettyPrint = true // 美化输出
}
// 字段重命名与缺省值
@Serializable
data class User(
@SerialName("user_name") val userName: String, // 对接下划线风格
val age: Int = 18 // 缺省字段可省略
)
// 可选字段用默认值表达,而非可空
@Serializable
data class Resp(val code: Int, val msg: String = "ok")配置要点:
1. @SerialName 解决 Kotlin 命名风格与后端字段名不一致
2. ignoreUnknownKeys 建议默认开启,接口加字段不炸客户端
3. 缺省值字段在 encodeDefaults=false 时不会输出
4. Json 实例可复用,避免每次解析都新建
6、多格式与多平台
除 JSON 外,同一套 @Serializable 模型可切换多种编码格式。
格式家族:
- JSON:kotlinx-serialization-json,Web 交互默认
- Protobuf:kotlinx-serialization-protobuf,二进制紧凑,跨端通信
- CBOR:kotlinx-serialization-cbor,IoT / 嵌入式场景常用
- Hocon:kotlinx-serialization-hocon,配置文件(Typesafe 风格)
- Properties:kotlinx-serialization-properties,.properties 键值
多平台要点:
1. commonMain 一份依赖,expect/actual 无需手写
2. Android 侧:库自带 ProGuard 规则,默认免配置
3. 注意:带命名 companion object 的类需额外混淆规则
4. Kotlin/JS 与 Native 直接可用,无 JVM 专属 API
7、定位对比:Kotlin JSON 库三选一
把 kotlinx.serialization、Gson 与 Jackson 放在一张桌上,各自的位置清晰起来。
三者对比:
- kotlinx.serialization:编译期生成、零反射、多平台、官方维护
- Gson:JVM 反射路线,接入零配置,但 Kotlin 特性支持不全、混容易踩坑
- Jackson:JVM 生态功能最全(树模型、流式、生态绑定),仅限 JVM
选型建议:
1. 纯 Kotlin / KMP 项目 → kotlinx.serialization 唯一正解
2. 老项目混 Java、模型共享 → Jackson / Gson
3. 需要流式解析大文件 → Jackson(kxser 走全量模型)
4. 组合玩法:对外 JSON 用 kxser,遗留系统网关层用 Jackson 转换
8、总结
kotlinx.serialization 是 Kotlin 官方的多平台多格式序列化方案(Apache-2.0、Stable):编译器插件生成 visitor 代码实现零反射,运行时库 1.11.0 与插件(随 Kotlin 2.3.20)双线发版;@Serializable 一个注解覆盖标准集合与可空类型,JSON、Protobuf、CBOR、Hocon、Properties 五格式开箱,JVM、JS、Native 三平台一致 API,Android 端自带混淆规则。文档、API 参考、Serialization Guide 齐备。
实践要点:Gradle 两步配置后从 @Serializable data class 起步;对接后端字段风格用 @SerialName 与 ignoreUnknownKeys 兜底;KMP 项目在 commonMain 引依赖即全平台生效;有命名 companion object 的序列化类需补 ProGuard 规则。插件版本必须与 Kotlin 编译器一致,1.4.0 以下 Kotlin 不受支持。

