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")
}
相关推荐
androidwork21 小时前
使用 Kotlin 和 Jetpack Compose 开发 Wear OS 应用的完整指南
android·kotlin
_龙小鱼_21 小时前
Kotlin变量与数据类型详解
开发语言·微信·kotlin
androidwork1 天前
掌握 Kotlin Android 单元测试:MockK 框架深度实践指南
android·kotlin
圈圈编码2 天前
MVVM框架
android·学习·kotlin
橙子199110162 天前
在 Kotlin 中,什么是解构,如何使用?
android·开发语言·kotlin
androidwork2 天前
Android 中使用通知(Kotlin 版)
android·kotlin
_龙小鱼_2 天前
卡顿检测与 Choreographer 原理
android·kotlin
androidwork3 天前
Kotlin Android单元测试MockK指南
android·kotlin
麻辣璐璐3 天前
Kotlin并发请求的一些知识记录
android·kotlin
androidwork3 天前
Arrow库:函数式编程在Kotlin Android中的深度实践
android·java·kotlin