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

Kotlinx.serialization 对多态对象(sealed class )支持更好用

为什么需要「多态对象」?

多个数据类型共享一个父类型时,我们希望都能用 同一种方式 序列化/反序列化。

现实类比:

比如消息系统里同属于 Message,但内容不同:

类型数据结构
文本消息{ "type": "text", "content": "hello" }
图片消息{ "type": "image", "url": "xxx.png" }

这些都是 Message,但字段不同。

你想写一个 List<Message>:

val list: List<Message> = listOf(TextMessage("hello"),ImageMessage("https://img.png")
)

但如果没有“多态”能力,序列化并不知道该怎么转成 JSON,更不知道怎么解析回来。

Kotlin 的 sealed class = “受控的多态”

sealed class = 父类 + 多个明确的子类(受限制)
好处:编译器能知道所有子类型 → 更安全也更容易序列化。

图理解👇:

      Message  ← Sealed Class/    \TextMessage  ImageMessage

Kotlinx.serialization 最爽的地方:天然支持 sealed class

只要用 @Serializable 标记 sealed class + 子类即可。

📌 注意:每个子类都要加 @Serializable

@Serializable
sealed class Message {@Serializable@SerialName("text")data class TextMessage(val content: String) : Message()@Serializable@SerialName("image")data class ImageMessage(val url: String) : Message()
}

序列化 —— 用 Json 编码成字符串

val json = Json {classDiscriminator = "type"  // JSON 的类型字段名
}val messages: List<Message> = listOf(Message.TextMessage("你好"),Message.ImageMessage("xx.png")
)val jsonStr = json.encodeToString(messages)
println(jsonStr)

输出 JSON:

[{"type": "text","content": "你好"},{"type": "image","url": "xx.png"}
]

你看到 "type": "text" 和 "type": "image" 就是用于表示它是哪种子类。

反序列化 —— Json 字符串解析回对象

val backToObject = json.decodeFromString<List<Message>>(jsonStr)
println(backToObject)

解析结果:

[TextMessage(content=你好),ImageMessage(url=xx.png)
]

就是这么丝滑,完全不用自己判断类型!

对比传统方案(比如 Gson/Moshi)

传统做法:

  • 需要写 Adapter/Factory

  • 手动注册每个子类

  • JSON → 手动判断 "type"

👉 Kotlinx.serialization:一行都不用写,自动处理。

传统方案(示例)

场景设定

有一个父类型:Animal
有两个子类:CatDog

后端返回的 JSON 大概是这样:

{"type":"cat","name":"Tom","lives":9}
{"type":"dog","name":"Spike","hasBone":true}
1. 定义父类和子类
open class Animaldata class Cat(val name: String,val lives: Int
) : Animal()data class Dog(val name: String,val hasBone: Boolean
) : Animal()
2. 写一个“适配器”(JsonDeserializer)

这个适配器负责:

  • 先读出 "type" 字段

  • 根据值是 "cat" 还是 "dog"

  • 再交给 Gson 去反序列化成具体子类

import com.google.gson.*
import java.lang.reflect.Typeclass AnimalDeserializer : JsonDeserializer<Animal> {override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Animal {val obj = json.asJsonObjectval type = obj.get("type")?.asString?: throw JsonParseException("missing type")return when (type) {"cat" -> context.deserialize<Cat>(obj, Cat::class.java)"dog" -> context.deserialize<Dog>(obj, Dog::class.java)else  -> throw JsonParseException("unknown type: $type")}}
}

核心就是 when (type) 那几行:手动判断 "type" → 手动决定用哪个子类去解析。

3. 在 Gson 里注册这个适配器
val gson = GsonBuilder().registerTypeAdapter(Animal::class.java, AnimalDeserializer()).create()
4. 使用:把 JSON 转成 Animal / List<Animal>

4.1 单个对象

val jsonCat = """{"type":"cat","name":"Tom","lives":9}"""
val cat: Animal = gson.fromJson(jsonCat, Animal::class.java)
// 实际类型是 Cat
println(cat)  // 输出:Cat(name=Tom, lives=9)

4.2 List<Animal>(要用 TypeToken)

val jsonList = """
[{"type":"cat","name":"Tom","lives":9},{"type":"dog","name":"Spike","hasBone":true}
]
""".trimIndent()val listType = object : com.google.gson.reflect.TypeToken<List<Animal>>() {}.type
val animals: List<Animal> = gson.fromJson(jsonList, listType)println(animals)
// [Cat(name=Tom, lives=9), Dog(name=Spike, hasBone=true)]
对比:

传统 Gson 多态:

  1. JSON 里要有个 "type" 字段(你自己约定)

  2. 写一个 JsonDeserializer<父类> / TypeAdapter<父类>

  3. 在里面:

    • 读 "type"

    • when (type) 分支判断

    • context.deserialize(...) 解析成对应的子类

  4. GsonBuilder.registerTypeAdapter(父类::class.java, 你的Adapter)

现在用 Kotlinx.serialization:

  • sealed class + @Serializable

  • Json { classDiscriminator = "type" }

  • 子类加 @SerialName("cat") / @SerialName("dog")

  • 根本不用自己写 “Adapter/Factory + when 判断” 那一坨。

sealed class 带来的额外好处

  • 编译器会强制你处理所有子类(更安全)

  • IDE 自动提示 when 不漏 case

例如:

when (msg) {is Message.TextMessage -> println("文本: " + msg.content)is Message.ImageMessage -> println("图片: " + msg.url)// 如果你忘记某个 case,会编译错误
}

总结(懂 sealed class = 懂多态序列化)

项目含义
sealed class定义父类 + 所有子类
多态不同子类共享同一父类型
Kotlinx.serialization 支持 sealed class自动识别类型,自动序列化

一句话:sealed class + Kotlinx.serialization = 多态序列化无痛方案

 

http://www.dtcms.com/a/618266.html

相关文章:

  • ArkTS接口与泛型在HarmonyOS应用开发中的深度应用
  • 4.4 跨越文本边界!多模态Agent开发实战,视觉+语言融合的新可能
  • 【数据结构】从零开始认识B树 --- 高效外查找的数据结构
  • 东莞seo网站排名优化建立外贸网站多少钱
  • 有没有什么做地堆的网站wordpress 文章摘要字数
  • stateflow和shareflow的区别
  • Qt QLibrary程序在运行时加载外部库
  • 电线电缆做销售哪个网站好海南哪家公司做网站做的好
  • 做it题的网站知名网站欣赏
  • 番禺做网站哪家强网站定位方案
  • 当AI学会叠衣服,我们才会真正需要它
  • Python中的输出函数
  • flash网站制作下载网站可以备案先提交类别后来改么
  • Maya 集成 pycharm(下载devkit、设置python运行环境、安装mayacharm插件、设置debug的配置)
  • AI工具在CTF中的战术应用
  • 乐清做网站建设行业管理信息系统官网
  • Rust 异步编程深度解析:从 Future 到运行时
  • Streaming ELT with Flink CDC · OceanBase Sink
  • 环境变量与地址
  • C/C++爱心①
  • 7.4、Python-变量的作用域
  • 英文专业的网站建设网站设计建设流程
  • 【教程】用Python复刻经典小游戏(贪吃蛇、扫雷)
  • 在智联招聘网站做销售最新国际足球世界排名
  • 垃圾回收算法(GC Algorithm)基石:标记-清除、复制、标记-整理
  • 中保研汽车小偏置碰撞案例分析
  • 广西建设厅查询网站wordpress 批量导入评论
  • AI工具 Claude code 常用命令和标注汇总
  • 车联网GPS测试:GPS动态欺骗测试 || GPS信号干扰测试.
  • <script setup> 实战模式:大型组件怎么拆?