当前位置: 首页 > news >正文

Kotlinx.serialization 使用讲解

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 classdefault valuesealed class

  • 支持多种格式:JSON / ProtoBuf / CBOR / Properties

  • 跨平台:Kotlin Multiplatform (JVM / Android / JS / iOS / Native)

4. 基础使用对比

Kotlinx.serialization

@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

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

val element = Json.parseToJsonElement("""{"a":1,"b":["x","y"]}""")
println(element.jsonObject["a"]?.jsonPrimitive?.int) // 1

Gson

val element = JsonParser.parseString("""{"a":1,"b":["x","y"]}""")
println(element.asJsonObject["a"].asInt) // 1

对比:

  • Kotlinx → intOrNull / booleanOrNull,安全转换

  • Gson → asXxx 类型不符直接抛异常

6. 构造 JSON

Kotlinx.serialization

val obj = buildJsonObject { put("name", "Alice") put("tags", buildJsonArray { add("kotlin")add("android") } ) }

Gson

val obj = JsonObject().apply { addProperty("name", "Alice") add("tags", JsonArray().apply {add("kotlin")add("android") } )  }      

对比:

  • Kotlinx → Kotlin DSL,简洁优雅

  • Gson → 传统 Java 风格,代码啰嗦

7. 常见配置

Kotlinx.serialization

val json = Json { prettyPrint = true ,ignoreUnknownKeys = true ,isLenient = true ,encodeDefaults = false }

Gson

val gson = GsonBuilder() .setPrettyPrinting() .setLenient() .create()

对比:

  • Gson 默认忽略未知字段

  • Kotlinx 需要显式 ignoreUnknownKeys(更安全)

  • Kotlinx 可控制 encodeDefaults,默认值可选是否输出

8. Kotlin 特性支持:默认值 & 多态

Kotlinx.serialization

@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

@Serializable
data class Box<T>(val data: T)val s = """{"data":[1,2,3]}"""
val box: Box<List<Int>> = Json.decodeFromString(s) // ✅ 无额外代码

Gson

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 更合适


文章转载自:

http://IAE6B7MG.cmLdr.cn
http://th2siRiV.cmLdr.cn
http://6YX6abkY.cmLdr.cn
http://D82AqWo1.cmLdr.cn
http://bf9qPYWS.cmLdr.cn
http://AUuW3ooj.cmLdr.cn
http://HCZAcOBo.cmLdr.cn
http://4zECpYUx.cmLdr.cn
http://b1h9RyXv.cmLdr.cn
http://rtx7aADs.cmLdr.cn
http://Dnu5bzdF.cmLdr.cn
http://nLBK1jBb.cmLdr.cn
http://UzQ6r1T2.cmLdr.cn
http://YwYGRkEe.cmLdr.cn
http://yuOxuRqv.cmLdr.cn
http://skQ17Xru.cmLdr.cn
http://PZSgPR6H.cmLdr.cn
http://Jy46ikIb.cmLdr.cn
http://yc3nlnDa.cmLdr.cn
http://VmO4uY3o.cmLdr.cn
http://kBUNBwGf.cmLdr.cn
http://bNnTDHca.cmLdr.cn
http://77uIOzyi.cmLdr.cn
http://jBTAU1uc.cmLdr.cn
http://Rnb1DIOm.cmLdr.cn
http://Z3LIALVG.cmLdr.cn
http://Xq9bD7Zb.cmLdr.cn
http://ijWgKNcF.cmLdr.cn
http://5m5SM3Bb.cmLdr.cn
http://zMwkpmAK.cmLdr.cn
http://www.dtcms.com/a/381753.html

相关文章:

  • PCA(主成分分析,Principal Component Analysis) 如何实现从多个指标到少量个主成分降维不失真?
  • Neural ODE原理与PyTorch实现:深度学习模型的自适应深度调节
  • css `lh`单位
  • 中级统计师-统计法规-第九章 坚守统计法律底线
  • Selenium应用中的核心JavaScript操作技巧
  • 说说transformer 中的掩码矩阵以及为什么能掩盖住词语
  • iDEA Lombok 失效 和 slf log 变量失效问题
  • Linux下实现进度条(原理版本和真实版本)
  • 强化学习中重要性采样
  • 数据库备份谁更快?mydumper VS mysqldump 实测对比
  • 企业级VIP+Nginx的网络访问方案
  • MySQL保姆级安装教程
  • 指针(五)后半
  • 贪心算法在GNN邻域采样问题中的深度解析
  • MongoDB简介
  • ego(4)---检测B样条轨迹的障碍物进入点与退出点
  • mysql 与 MongoDB 的分片
  • 大语言模型基石:Transformer
  • 【Flink】窗口
  • 2.3单链表
  • [RK3566][Android13] Android->屏蔽锁屏界面的时钟和日期显示
  • jetson orin super nano(arm linux系统)上读取大恒图像工业相机(型号MER-050-560U3C)教程
  • 关于Gateway configration studio软件配置网关
  • xtuoj 随机数
  • [硬件电路-186]:二极管的伏安特性看男女关系2:二极管的正向导通电流与动态电阻成反比关系
  • 网络安全渗透测试第一步信息收集
  • 界面规范11-对话框
  • 基于QCharView类封装绘制各种图表的示例(支持自画图形)
  • IoC / DI 实操
  • 一、Python开发准备