在 Kotlin 中处理 JSON:面向初学者的解析与序列化
JSON(JavaScript Object Notation)是现代 Web 应用程序和 API 中最流行的数据交换格式。如果您开始学习 Kotlin,那么迟早会遇到需要将 JSON 字符串转换为应用程序对象(反序列化或解析)以及反向转换(序列化)的情况。
在本文中,我们将以三种流行的库为例,介绍在 Kotlin 中处理 JSON 的主要方法:kotlinx.serialization、Gson 和 Moshi。您将了解如何快速开始解析 JSON 并无复杂地序列化数据。
什么是 JSON 解析和序列化?
在进入代码之前,让我们先明确术语:
- 序列化 — 是将对象(例如 Kotlin 数据类)转换为 JSON 格式字符串的过程。
- 解析(反序列化) — 是相反的过程:从 JSON 字符串中获取特定类型的对象。
在 Kotlin 中处理 JSON 可以通过多种方式实现。该语言没有内置的 JSON 支持,因此我们使用第三方库。
kotlinx.serialization 库(推荐方式)
kotlinx.serialization 是 JetBrains 的官方库,与 Kotlin 语言完美集成。它支持多平台(JVM、JS、Native)并在编译阶段工作,使其非常快速和安全。
安装
在 build.gradle.kts 文件中添加插件:
plugins { kotlin("plugin.serialization") version "1.9.0"}
dependencies { implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.0")}示例:解析 JSON
假设我们有一个包含用户数据的 JSON:
{ "name": "伊万", "age": 28, "email": "ivan@example.com"}创建一个数据类并使用 @Serializable 注解标记它:
import kotlinx.serialization.Serializableimport kotlinx.serialization.json.Json
@Serializabledata class User( val name: String, val age: Int, val email: String)
fun main() { val jsonString = """ {"name": "伊万", "age": 28, "email": "ivan@example.com"} """.trimIndent()
val user = Json.decodeFromString<User>(jsonString) println(user) // User(name=伊万, age=28, email=ivan@example.com)}示例:序列化为 JSON
fun main() { val user = User(name = "安娜", age = 25, email = "anna@example.com") val jsonString = Json.encodeToString(user) println(jsonString) // {"name":"安娜","age":25,"email":"anna@example.com"}}优点:类型安全、速度快、无反射、支持可空字段、默认值和嵌套对象。
Gson 库(来自 Google)
Gson 是 JVM 生态系统中用于处理 JSON 的最古老、最流行的库之一。它使用简单,但使用反射,因此比 kotlinx.serialization 稍慢。
安装
dependencies { implementation("com.google.code.gson:gson:2.10.1")}示例:解析 JSON
import com.google.gson.Gson
data class Product( val id: Int, val title: String, val price: Double)
fun main() { val gson = Gson() val jsonString = """{"id": 101, "title": "笔记本电脑", "price": 75000.0}"""
val product = gson.fromJson(jsonString, Product::class.java) println(product) // Product(id=101, title=笔记本电脑, price=75000.0)}示例:序列化为 JSON
fun main() { val product = Product(id = 202, title = "鼠标", price = 2