Kotlin中的序列化应用

Kotlin 序列化库 kotlinx.serialization 是一个强大的工具,可用于序列化和反序列化复杂的数据结构。

1,首先需要添加依赖

在模块级的build.gradle.kts(:app)中:

scss 复制代码
plugins {
    ......
	// 下面代码中version中代码中Kotlin的版本号
    kotlin("plugin.serialization") version "2.0.0"
}
dependencies {
	......
	implementation(libs.serialization.json)
	......
}

在libs.versions.toml文件中:

ini 复制代码
[versions]
serialization-json = "1.8.1"

[libraries]
serialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version.ref = "serialization-json"}

2,定义可序列化的数据结构

要确保数据结构的类被 @Serializable 注解标记。

kotlin 复制代码
import kotlinx.serialization.Serializable

@Serializable
data class Person(
    val name: String,
    val age: Int,
    val address: Address,
    val hobbies: List<String>
)

@Serializable
data class Address(
    val street: String,
    val city: String,
    val zipCode: String
)

3,序列化数据结构

借助 kotlinx.serialization.json.Json 类的 encodeToString 方法,能够将对象序列化为 JSON 字符串。

kotlin 复制代码
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

fun main() {
    val address = Address("123 Main St", "Anytown", "12345")
    val person = Person("John Doe", 30, address, listOf("Reading", "Running"))

    val jsonString = Json.encodeToString(person)
    println("Serialized JSON: $jsonString")
}

4,反序列化数据结构

使用 kotlinx.serialization.json.Json 类的 decodeFromString 方法,可将 JSON 字符串反序列化为对象。

javascript 复制代码
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

fun main() {
    val jsonString = """
        {
            "name": "John Doe",
            "age": 30,
            "address": {
                "street": "123 Main St",
                "city": "Anytown",
                "zipCode": "12345"
            },
            "hobbies": ["Reading", "Running"]
        }
    """.trimIndent()

    val person = Json.decodeFromString<Person>(jsonString)
    println("Deserialized Person: $person")
}

5, 处理嵌套集合等复杂情况

若数据结构包含嵌套集合,序列化和反序列化的过程是一样的。

kotlin 复制代码
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json

@Serializable
data class School(
    val name: String,
    val classes: List<ClassRoom>
)

@Serializable
data class ClassRoom(
    val grade: Int,
    val students: List<Student>
)

@Serializable
data class Student(
    val name: String,
    val age: Int
)

fun main() {
    val student1 = Student("Alice", 12)
    val student2 = Student("Bob", 13)
    val classRoom = ClassRoom(6, listOf(student1, student2))
    val school = School("ABC School", listOf(classRoom))

    val jsonString = Json.encodeToString(school)
    println("Serialized JSON: $jsonString")

    val deserializedSchool = Json.decodeFromString<School>(jsonString)
    println("Deserialized School: $deserializedSchool")
}

6,自定义序列化器

在某些情况下,默认的序列化器可能无法满足需求,这时可以自定义序列化器。

kotlin 复制代码
// 导入 kotlinx.serialization 库的所有基础类和注解,这些是实现序列化和反序列化功能的核心。
import kotlinx.serialization.*
// 用于表示基本数据类型的枚举类,在定义序列化描述符时会用到。
import kotlinx.serialization.descriptors.PrimitiveKind
// 用于创建基本数据类型的序列化描述符
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
// 序列化描述符的接口,描述了数据类型的结构,序列化和反序列化过程中会用到。
import kotlinx.serialization.descriptors.SerialDescriptor
// 用于从输入流中读取数据并将其转换为对象的接口,在反序列化时使用。
import kotlinx.serialization.encoding.Decoder
// 用于将对象转换为输出流的接口,在序列化时使用。
import kotlinx.serialization.encoding.Encoder
// 用于处理 JSON 格式的序列化和反序列化的类。
import kotlinx.serialization.json.Json

//@Serializable(with = CustomDateSerializer::class):
// 这是一个序列化注解,表明 Event 类是可序列化的。
// with 参数指定了使用自定义的序列化器 CustomDateSerializer 来处理 Event 类中的 date 字段。
@Serializable(with = CustomDateSerializer::class)
// 定义了一个名为 Event 的数据类,包含两个属性:name(字符串类型)和 date(java.util.Date 类型)。
data class Event(val name: String, val date: java.util.Date)

// 使用 object 关键字定义了一个单例对象 CustomDateSerializer,
// 它实现了 KSerializer<java.util.Date> 接口,用于处理 java.util.Date 类型的序列化和反序列化。
object CustomDateSerializer : KSerializer<java.util.Date> {
    // override val descriptor 重写了 KSerializer 接口中的 descriptor 属性, 用于描述序列化的数据类型。
    // 这里使用 PrimitiveSerialDescriptor 创建了一个描述符,表明 Date 类型将被序列化为一个长整型(PrimitiveKind.LONG)。
    override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG)

    // 重写了 KSerializer 接口中的 serialize 方法,用于将 java.util.Date 对象序列化为长整型。
    override fun serialize(encoder: Encoder, value: java.util.Date) {
        // 使用 Encoder 对象的 encodeLong 方法将 Date 对象的时间戳(通过 value.time 获取)写入输出流。
        encoder.encodeLong(value.time)
    }

    // 重写了 KSerializer 接口中的 deserialize 方法,用于从输入流中读取长整型数据并将其转换为 java.util.Date 对象。
    override fun deserialize(decoder: Decoder): java.util.Date {
        // 使用 Decoder 对象的 decodeLong 方法从输入流中读取长整型数据,然后将其作为参数传递给 java.util.Date 的构造函数,创建一个新的 Date 对象。
        return java.util.Date(decoder.decodeLong())
    }
}

fun main() {
    // 创建了一个 Event 对象,name 属性为 "Conference",date 属性为当前时间。
    val event = Event("Conference", java.util.Date())
    // 使用 Json 类的 encodeToString 方法将 Event 对象序列化为 JSON 字符串。
    val jsonString = Json.encodeToString(event)
    println("Serialized JSON: $jsonString")
    // 使用 Json 类的 decodeFromString 方法将 JSON 字符串反序列化为 Event 对象。
    val deserializedEvent = Json.decodeFromString<Event>(jsonString)
    println("Deserialized Event: $deserializedEvent")
}
相关推荐
hsx66614 小时前
Kotlin 协程中的 Dispatchers
kotlin
每次的天空17 小时前
Android-重学kotlin(协程源码第二阶段)新学习总结
android·学习·kotlin
stevenzqzq17 小时前
Kotlin 中主构造函数和次构造函数的区别
android·kotlin
开发者如是说20 小时前
言叶是如何对文件进行端到端加密的
android·kotlin·swift
小李飞飞砖21 小时前
kotlin
开发语言·单例模式·kotlin
小李飞飞砖21 小时前
kotlin中的冷流和热流
android·开发语言·kotlin
Kotlin上海用户组2 天前
Koin vs. Hilt——最流行的 Android DI 框架全方位对比
android·架构·kotlin
Kapaseker2 天前
当Object遇到Json你可能会碰到的坑
kotlin
RichardLai882 天前
Kotlin Flow:构建响应式流的现代 Kotlin 之道
android·前端·kotlin
程序员江同学2 天前
Kotlin/Native 编译流程浅析
android·kotlin