1. 背景
-
JSON 序列化/反序列化在 Android 和服务端开发中非常常见。
-
Gson:Google 出品,生态成熟,但基于反射,性能一般,不支持 Kotlin 特性,仅支持 JSON。
-
Kotlinx.serialization:JetBrains 官方出品,Kotlin-first,性能更优,支持多平台和 Kotlin 特性。
2. Gson 回顾
-
历史悠久(2008 年推出),Java/Android 项目主流
-
基于反射 → 简单但性能开销大
-
只支持 JSON
-
优点:成熟稳定、生态广、学习成本低
-
缺点:
-
不支持 Kotlin 特性(默认值、sealed class、多平台)
-
Proguard 混淆要配置 keep
-
3. Kotlinx.serialization 简介
-
JetBrains 官方库,2017+,Kotlin-first
-
编译期生成序列化器 → 无反射,性能更优
-
原生支持:
data class
、default value
、sealed class
-
支持多种格式:JSON / ProtoBuf / CBOR / Properties
-
跨平台:Kotlin Multiplatform (JVM / Android / JS / iOS / Native)
4. 基础使用对比
Kotlinx.serialization
Kotlin
@Serializable
data class User(val name: String, val age: Int, val email: String? = null)
val json = Json { ignoreUnknownKeys = true }
val user = json.decodeFromString<User>("""{"name":"Alice","age":25,"extra":"xxx"}""")
val str = json.encodeToString(user)
Gson
Kotlin
data class User(val name: String, val age: Int, val email: String? = null)
val gson = Gson()
val user = gson.fromJson("""{"name":"Alice","age":25}""", User::class.java)
val str = gson.toJson(user)
对比:
-
Kotlinx → 编译期安全,
decodeFromString<T>()
泛型友好 -
Gson → 运行时反射,需要传
Class
,泛型要用TypeToken
5. 动态 JSON(JsonElement)
Kotlinx.serialization
Kotlin
val element = Json.parseToJsonElement("""{"a":1,"b":["x","y"]}""")
println(element.jsonObject["a"]?.jsonPrimitive?.int) // 1
Gson
Kotlin
val element = JsonParser.parseString("""{"a":1,"b":["x","y"]}""")
println(element.asJsonObject["a"].asInt) // 1
对比:
-
Kotlinx →
intOrNull
/booleanOrNull
,安全转换 -
Gson →
asXxx
类型不符直接抛异常
6. 构造 JSON
Kotlinx.serialization
Kotlin
val obj = buildJsonObject {
put("name", "Alice")
put("tags", buildJsonArray {
add("kotlin")
add("android")
} )
}
Gson
Kotlin
val obj = JsonObject().apply {
addProperty("name", "Alice")
add("tags", JsonArray().apply {
add("kotlin")
add("android")
} )
}
对比:
-
Kotlinx → Kotlin DSL,简洁优雅
-
Gson → 传统 Java 风格,代码啰嗦
7. 常见配置
Kotlinx.serialization
Kotlin
val json = Json {
prettyPrint = true ,
ignoreUnknownKeys = true ,
isLenient = true ,
encodeDefaults = false }
Gson
Kotlin
val gson = GsonBuilder()
.setPrettyPrinting()
.setLenient()
.create()
对比:
-
Gson 默认忽略未知字段
-
Kotlinx 需要显式
ignoreUnknownKeys
(更安全) -
Kotlinx 可控制
encodeDefaults
,默认值可选是否输出
8. Kotlin 特性支持:默认值 & 多态
Kotlinx.serialization
Kotlin
@Serializable
sealed class Message {
@Serializable data class Text(val content: String): Message()
@Serializable data class Image(val url: String, val w: Int = 0): Message() // 默认值
}
val msg: Message = Message.Image("http://x", w = 640)
val str = Json { encodeDefaults = false }.encodeToString(msg)
// 默认值可选择是否写入 JSON
对比:
-
Kotlinx → 默认值与 sealed class 原生支持
-
Gson → 默认值策略需自定义;sealed class 需手写 TypeAdapter
9. 泛型处理差异
Kotlinx.serialization
Kotlin
@Serializable
data class Box<T>(val data: T)
val s = """{"data":[1,2,3]}"""
val box: Box<List<Int>> = Json.decodeFromString(s) // ✅ 无额外代码
Gson
Kotlin
data class Box<T>(val data: T)
val s = """{"data":[1,2,3]}"""
val type = object : TypeToken<Box<List<Int>>>() {}.type
val box: Box<List<Int>> = Gson().fromJson(s, type) // 需要 TypeToken
10. 性能与场景对比
-
Kotlinx.serialization
-
编译期生成,无反射,性能好
-
跨平台支持(KMP)
-
适合新项目 & Kotlin-first 场景
-
-
Gson
-
基于反射,性能较低
-
流式解析(
JsonReader
/JsonWriter
)更方便 -
适合存量 Java/Android 项目
-
11. 迁移建议
-
新 Kotlin 项目 → 推荐用 Kotlinx.serialization
-
老项目(大量 Gson) → 可逐步迁移,先新模块用 Kotlinx
-
大文件流式处理 → Gson 的
JsonReader/Writer
仍然更直观
12. 总结
-
Gson:成熟稳定,生态广,Java 项目首选,但局限于反射 + JSON-only
-
Kotlinx.serialization:现代高效,Kotlin-first,支持多平台和 Kotlin 特性
👉 最佳实践:
-
新 Kotlin 项目 → 优先 Kotlinx.serialization
-
维护 Java/老项目 → 继续 Gson
-
流式大 JSON → Gson 更合适