01.Kotlin Serialization - 入门指南

534 阅读3分钟

📖 前言

在现代软件开发中,数据序列化是将对象转换为可存储或传输格式的关键技术。Kotlin Serialization 是 JetBrains 官方推出的序列化框架,为开发者提供了类型安全、高性能的序列化解决方案。

本文将带你初步探索 Kotlin Serialization 的世界,了解什么是可序列化类型,并掌握基础的序列化操作技巧。

说明:JSON 作为当前应用最广泛的数据传输格式,将是本系列教程的主要讲解对象。

🔧 项目配置

Gradle 配置(Kotlin DSL)

build.gradle.kts 文件中添加必要的插件和依赖:

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

dependencies {
    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0")
}

Gradle 配置(Groovy DSL)

如果使用传统的 build.gradle 文件:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '2.2.0'
    id 'org.jetbrains.kotlin.plugin.serialization' version '2.2.20'
}

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0'
}

📝 可序列化类型

只有可序列化的类型才能进行序列化和反序列化操作。那么,哪些类型是可序列化的呢?

Kotlin Serialization 支持两大类可序列化类型:

  • 自定义类型:使用 @Serializable 注解标记的类
  • 内置类型:Kotlin Serialization 框架内置支持的类型

📦 内置支持的类型

基础类型(Primitives)

  • 数值类型:ByteShortIntLongFloatDouble
  • 其他基础类型:BooleanCharString
  • 枚举类:所有枚举类都自动支持序列化(无需添加 @Serializable 注解)

集合类型(Collections)

  • 列表:List<T>MutableList<T>ArrayList<T>
  • 集合:Set<T>MutableSet<T>HashSet<T>LinkedHashSet<T>
  • 映射:Map<K,V>MutableMap<K,V>HashMap<K,V>LinkedHashMap<K,V>

数组类型(Arrays)

  • 泛型数组:Array<T>
  • 基础类型数组:ByteArrayShortArrayIntArrayLongArrayFloatArrayDoubleArrayBooleanArrayCharArray

复合类型(Composites)

  • 元组:Pair<A,B>Triple<A,B,C>
  • 特殊类型:Unit(序列化为空对象 {}
  • 时间类型:Duration(自 Kotlin 1.7.20 版本开始支持)

特殊类型

  • Nothing:见文末介绍

🚀 实战示例

让我们通过一个完整的示例来演示 Kotlin Serialization 的基本用法:

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

@Serializable
data class Student(
    val id: Int,
    val name: String,
    val address: Address,
)

@Serializable
data class Address(
    val city: String,
    val email: String?,
)

fun main() {
    // 创建学生对象
    val student = Student(
        id = 10001,
        name = "iKun",
        address = Address(city = "北京", email = null),
    )

    // 序列化:对象 -> JSON 字符串
    val jsonString = Json.encodeToString(student)
    println(jsonString)
    // 输出:{"id":10001,"name":"iKun","address":{"city":"北京","email":null}}

    // 反序列化:JSON 字符串 -> 对象
    val deserializedStudent = Json.decodeFromString<Student>(jsonString)
    println(deserializedStudent)
    // 输出:Student(id=10001, name=iKun, address=Address(city=北京, email=null))
}

通过这个示例,我们可以看到:

  1. 使用 @Serializable 注解标记需要序列化的类
  2. 使用 Json.encodeToString() 将对象序列化为 JSON 字符串
  3. 使用 Json.decodeFromString<T>() 将 JSON 字符串反序列化为对象

这就是 Kotlin Serialization 的基本用法,简单而强大!

🔍 深入理解:Nothing 类型

在前面提到的特殊类型中,Nothing 类型值得特别说明。虽然 Nothing 默认是可序列化的,但它有着独特的特性:

基本特性

  • 无实例存在Nothing 类型没有任何实例
  • 序列化必定失败:任何尝试直接序列化或反序列化 Nothing 的操作都会抛出异常
  • 语法占位符:主要用作类型系统中的占位符,而非实际序列化

典型应用场景

Nothing 最常见的用途是在参数化多态基类中作为类型参数:

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

@Serializable
sealed class Response<out T> {
    @Serializable
    @SerialName("success")
    data class Success<T>(val data: T) : Response<T>()

    @Serializable
    @SerialName("error")
    object Error : Response<Nothing>()  // 使用 Nothing 作为类型参数
}

fun main() {
    val successResponse: Response<String> = Response.Success("操作成功")
    val errorResponse: Response<Nothing> = Response.Error

    // 序列化成功响应
    val json1 = Json.encodeToString(successResponse)
    println(json1)
    // 输出:{"type":"success","data":"操作成功"}

    // 序列化错误响应
    val json2 = Json.encodeToString(errorResponse)
    println(json2)
    // 输出:{"type":"error"}
    // 注意:Nothing 的序列化器在这里并未被实际使用
}

设计意义

这种设计让我们能够:

  • 保持类型安全:满足泛型语法要求
  • 优雅处理特殊情况:如错误状态、空状态等场景
  • 避免不必要的数据:错误响应不需要携带具体的数据内容

Nothing 在序列化框架中体现了 Kotlin 类型系统的精妙设计,它在语法层面提供了完整性,在实现层面保持了合理性。