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")
}
相关推荐
Haha_bj14 小时前
七、Kotlin——扩展(Extensions)
android·kotlin
urkay-14 小时前
Android getDrawingCache 过时废弃
android·java·开发语言·kotlin·iphone·androidx
用户693717500138417 小时前
24.Kotlin 继承:调用超类实现 (super)
android·后端·kotlin
alexhilton20 小时前
借助RemoteCompose开发动态化页面
android·kotlin·android jetpack
QING6181 天前
Jetpack Compose Brush API 简单使用实战 —— 新手指南
android·kotlin·android jetpack
QING6181 天前
Jetpack Compose Brush API 详解 —— 新手指南
android·kotlin·android jetpack
鹿里噜哩1 天前
Spring Authorization Server 打造认证中心(二)自定义数据库表
spring boot·后端·kotlin
用户69371750013842 天前
23.Kotlin 继承:继承的细节:覆盖方法与属性
android·后端·kotlin
Haha_bj2 天前
五、Kotlin——条件控制、循环控制
android·kotlin
Kapaseker2 天前
不卖课,纯干货!Android分层你知多少?
android·kotlin