GSON的各种使用方式

  • Gson
    这是Gson的核心类,它可以将对象转换为JSON字符串,或者将JSON字符串转换为对象。它使用反射机制来自动匹配对象的字段和JSON的属性,不需要额外的配置或注解。它适合处理简单和稳定的数据结构,例如用户信息、商品列表等。使用方法是创建一个Gson对象,然后调用其toJson()和fromJson()方法。
// 创建一个Gson对象
val gson = Gson()

// 创建一个表示用户的类User
data class User(
    val id: Int,
    val name: String,
    val email: String,
    val phone: String
)

// 创建一个User对象
val user = User(1, "Alice", "alice@gmail.com", "1234567890")

// 使用Gson对象的toJson()方法将User对象转换为JSON字符串
val json = gson.toJson(user) // {"id":1,"name":"Alice","email":"alice@gmail.com","phone":"1234567890"}

// 使用Gson对象的fromJson()方法将JSON字符串转换为User对象
val user2 = gson.fromJson(json, User::class.java) // User(id=1, name=Alice, email=alice@gmail.com, phone=1234567890)
  • GsonBuilder
    这是一个辅助类,它可以让您定制Gson的行为和特性,例如设置日期格式、排除策略、版本控制、自定义序列化和反序列化等。它适合处理复杂和灵活的数据结构,例如泛型、循环引用、动态类型等。使用方法是创建一个GsonBuilder对象,然后调用其各种设置方法,最后调用其create()方法来生成一个Gson对象。

// 创建一个GsonBuilder对象
val gsonBuilder = GsonBuilder()

//省略配置代码

// 使用GsonBuilder对象的create()方法来生成一个Gson对象
val gson2 = gsonBuilder.create()
  • JsonReader
    这是一个读取JSON数据的类,它可以让您以流式的方式读取JSON数据,而不需要将整个JSON文档加载到内存中。它适合处理大型和未知的JSON数据,例如网络响应、日志文件等。使用方法是创建一个JsonReader对象,然后调用其各种读取方法,如beginObject()、endObject()、nextName()、nextString()等。
// 创建一个JsonReader对象,用于读取JSON数据
val jsonReader = JsonReader(FileReader("test.json")) // 从文件中读取JSON数据

// 使用JsonReader对象的各种读取方法,以流式的方式读取JSON数据,而不需要将整个JSON文档加载到内存中
jsonReader.beginObject() // 开始读取一个JSON对象
while (jsonReader.hasNext()) { // 循环读取每个键值对
    val name = jsonReader.nextName() // 读取键名
    when (name) { // 根据键名判断值的类型和处理逻辑
        "id" -> {
            val id = jsonReader.nextInt() // 读取整数值
            println("id: $id")
        }
        "name" -> {
            val name = jsonReader.nextString() // 读取字符串值
            println("name: $name")
        }
        "email" -> {
            val email = jsonReader.nextString() // 读取字符串值
            println("email: $email")
        }
        "phone" -> {
            val phone = jsonReader.nextString() // 读取字符串值
            println("phone: $phone")
        }
        else -> {
            jsonReader.skipValue() // 跳过其他值
        }
    }
}
jsonReader.endObject() // 结束读取一个JSON对象
  • JsonWriter
    这是一个写入JSON数据的类,它可以让您以流式的方式写入JSON数据,而不需要创建一个完整的JSON对象。它适合处理大型和未知的JSON数据,例如网络请求、日志文件等。使用方法是创建一个JsonWriter对象,然后调用其各种写入方法,如beginObject()、endObject()、name()、value()等。
// 创建一个JsonWriter对象,用于写入JSON数据
val jsonWriter = JsonWriter(FileWriter("test.json")) // 写入JSON数据到文件中

// 使用JsonWriter对象的各种写入方法,以流式的方式写入JSON数据,而不需要创建一个完整的JSON对象
jsonWriter.beginObject() // 开始写入一个JSON对象
jsonWriter.name("id").value(1) // 写入一个键值对,键名为id,值为1
jsonWriter.name("name").value("Alice") // 写入一个键值对,键名为name,值为Alice
jsonWriter.name("email").value("alice@gmail.com") // 写入一个键值对,键名为email,值为alice@gmail.com
jsonWriter.name("phone").value("1234567890") // 写入一个键值对,键名为phone,值为1234567890
jsonWriter.endObject() // 结束写
  • JsonParser
    这是一个解析JSON数据的类,它可以让您将JSON数据表示为一棵树状的结构,每个节点都是一个JsonElement对象,可以是JsonObject、JsonArray、JsonPrimitive或JsonNull。它适合处理动态和不规则的JSON数据,例如用户输入、配置文件等。使用方法是创建一个JsonParser对象,然后调用其parse()方法来解析JSON字符串为一个JsonElement对象 。
// 创建一个JsonParser对象,用于解析JSON数据
val jsonParser = JsonParser()

// 使用JsonParser对象的parse()方法来解析JSON字符串为一个JsonElement对象
val jsonElement = jsonParser.parse(json) // 解析JSON字符串为一个JsonElement对象
  • JsonElement
    这是一个抽象类,它是所有JSON元素的基类。它提供了一些通用的方法,如isJsonObject()、isJsonArray()、isJsonPrimitive()、isJsonNull()等来判断元素的类型,以及getAsJsonObject()、getAsJsonArray()、getAsJsonPrimitive()、getAsJsonNull()等来获取元素的具体类型。
// 使用JsonParser对象的parse()方法来解析JSON字符串为一个JsonElement对象
val jsonElement = jsonParser.parse(json) // 解析JSON字符串为一个JsonElement对象

// 使用JsonElement对象的各种方法,将JSON数据表示为一棵树状的结构,每个节点都是一个JsonElement对象,可以是JsonObject、JsonArray、JsonPrimitive或JsonNull
if (jsonElement.isJsonObject) { // 判断是否是一个JSON对象
    val jsonObject = jsonElement.asJsonObject // 获取JSON对象
    if (jsonObject.has("id")) { // 判断是否有id属性
        val id = jsonObject.get("id").asInt // 获取id属性的值
        println("id: $id")
    }
    if (jsonObject.has("name")) { // 判断是否有name属性
        val name = jsonObject.get("name").asString // 获取name属性的值
        println("name: $name")
    }
    if (jsonObject.has("email")) { // 判断是否有email属性
        val email = jsonObject.get("email").asString // 获取email属性的值
        println("email: $email")
    }
    if (jsonObject.has("phone")) { // 判断是否有phone属性
        val phone = jsonObject.get("phone").asString // 获取phone属性的值
        println("phone: $phone")
    }
}
  • JsonObject
    这是一个继承自JsonElement的类,它表示一个JSON对象。它提供了一些操作键值对的方法,如add()、remove()、get()、has()等。
gsonBuilder.registerTypeAdapter(Book::class.java, object : JsonSerializer<Book> { // 注册自定义序列化器
    override fun serialize(src: Book, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
        val jsonObject = JsonObject()
        jsonObject.addProperty("id", src.id)
        jsonObject.addProperty("title", src.title.toUpperCase()) // 将标题转换为大写
        jsonObject.addProperty("author", src.author)
        return jsonObject
    }
})
  • JsonArray
    这是一个继承自JsonElement的类,它表示一个JSON数组。它提供了一些操作元素的方法,如add()、remove()、get()、size()等。

  • JsonPrimitive:
    这是一个继承自JsonElement的类,它表示一个JSON原始值。它可以是一个字符串、数字、布尔值或空值。它提供了一些获取值的方法,如getAsString()、getAsInt()、getAsBoolean()等。

  • JsonNull:
    这是一个继承自JsonElement的类,它表示一个JSON空值。它是一个单例类,只有一个实例。

  • InstanceCreator:
    这是一个创建对象实例的接口,它可以让您为特定的类型提供自定义的构造方法。它适合处理没有无参构造器或有特殊初始化逻辑的类,例如抽象类、接口、内部类等。使用方法是实现这个接口,并重写createInstance()方法,然后注册到GsonBuilder中。

  • JsonSerializer
    这是一个自定义序列化的接口,它可以让您为特定的类型提供自定义的序列化方法。它适合处理复杂的泛型、循环引用、动态类型等情况,或者需要修改或增加JSON属性等情况。使用方法是实现这个接口,并重写serialize()方法,然后注册到GsonBuilder中。
gsonBuilder.registerTypeAdapter(Book::class.java, object : JsonSerializer<Book> { // 注册自定义序列化器
    override fun serialize(src: Book, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
        val jsonObject = JsonObject()
        jsonObject.addProperty("id", src.id)
        jsonObject.addProperty("title", src.title.toUpperCase()) // 将标题转换为大写
        jsonObject.addProperty("author", src.author)
        return jsonObject
    }
})
  • JsonDeserializer
    这是一个自定义反序列化的接口,它可以让您为特定的类型提供自定义的反序列化方法。它适合处理复杂的泛型、循环引用、动态类型等情况,或者需要验证或转换JSON属性等情况。使用方法是实现这个接口,并重写deserialize()方法,然后注册到GsonBuilder中。
gsonBuilder.registerTypeAdapter(Book::class.java, object : JsonDeserializer<Book> { // 注册自定义反序列化器
    override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Book {
        val jsonObject = json.asJsonObject
        val id = jsonObject.get("id").asInt
        val title = jsonObject.get("title").asString.toLowerCase() // 将标题转换为小写
        val author = jsonObject.get("author").asString
        return Book(id, title, author)
    }
})
  • TypeAdapter
    这是一个抽象类,它可以让您完全控制对象和JSON之间的转换过程。它适合处理日期格式、枚举类型、自定义类型等情况,或者需要优化性能或内存消耗等情况。使用方法是继承这个类,并重写write()和read()方法,然后注册到GsonBuilder中。
// 创建一个表示颜色的枚举类Color,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
enum class Color {
    @TypeAdapter(ColorTypeAdapter::class)
    RED,
    GREEN,
    BLUE
}

// 创建一个自定义的TypeAdapter类,用于控制Color枚举类和JSON之间的转换过程
class ColorTypeAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter, value: Color) {
        out.value(value.ordinal) // 将枚举值转换为整数值写入JSON中
    }

    override fun read(`in`: JsonReader): Color {
        return Color.values()[`in`.nextInt()] // 将整数值从JSON中读取并转换为枚举值
    }
}

// 创建一个表示画笔的类Pen,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
data class Pen(
    val brand: String,
    val color: Color,
    val price: Double
) {
    @TypeAdapter(PenTypeAdapter::class)
    constructor(json: String) : this("", Color.RED, 0.0) // 使用一个带有JSON字符串参数的构造器,并使用@TypeAdapter注解来指定




// 创建一个表示颜色的枚举类Color,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
enum class Color {
    @TypeAdapter(ColorTypeAdapter::class)
    RED,
    GREEN,
    BLUE
}

// 创建一个自定义的TypeAdapter类,用于控制Color枚举类和JSON之间的转换过程
class ColorTypeAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter, value: Color) {
        out.value(value.ordinal) // 将枚举值转换为整数值写入JSON中
    }

    override fun read(`in`: JsonReader): Color {
        return Color.values()[`in`.nextInt()] // 将整数值从JSON中读取并转换为枚举值
    }
}

// 创建一个表示画笔的类Pen,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
data class Pen(
    val brand: String,
    val color: Color,
    val price: Double
) {
    @TypeAdapter(PenTypeAdapter::class)
    constructor(json: String) : this("", Color.RED, 0.0) // 使用一个带有JSON字符串参数的构造器,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
}

// 创建一个自定义的TypeAdapter类,用于控制Pen类和JSON之间的转换过程
class PenTypeAdapter : TypeAdapter<Pen>() {
    override fun write(out: JsonWriter, value: Pen) {
        out.beginObject() // 开始写入一个JSON对象
        out.name("brand").value(value.brand) // 写入一个键值对,键名为brand,值为画笔品牌
        out.name("color").value(value.color.ordinal) // 写入一个键值对,键名为color,值为画笔颜色对应的整数值
        out.name("price").value(value.price) // 写入一个键值对,键名为price,值为画笔价格
        out.endObject() // 结束写入一个JSON对象
    }

    override fun read(`in`: JsonReader): Pen {
        var brand = ""
        var color = Color.RED
        var price = 0.0
        `in`.beginObject() // 开始读取一个JSON对象
        while (`in`.hasNext()) { // 循环读取每个键值对
            val name = `in`.nextName() // 读取键名
            when (name) { // 根据键名判断值的类型和处理逻辑
                "brand" -> {
                    brand = `in`.nextString() // 读取字符串值作为画笔品牌
                }
                "color" -> {
                    color = Color.values()[`in`.nextInt()] // 读取整数值并转换为画笔颜色对应的枚举值
                }
                "price" -> {
                    price = `in`.nextDouble() // 读取浮点数值作为画笔价格
                }
                else -> {
                    `in`.skipValue() // 跳过其他值
                }
            }
        }
        `in`.endObject() // 结束读取一个JSON对象
        return Pen(brand, color, price) // 返回一个Pen对象
    }
}

// 创建一个Pen对象
val pen = Pen("Pilot", Color.BLUE, 10.0)

// 使用生成的Gson对象的toJson()方法将Pen对象转换为JSON字符串,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val json7 = gson2.toJson(pen) // {"brand":"Pilot","color":2,"price":10.0}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Pen对象,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val pen2 = gson2.fromJson(json7, Pen::class.java) // Pen(brand=Pilot, color=BLUE, price=10.0)

// 使用带有JSON字符串参数的构造器来创建一个Pen对象,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val pen3 = Pen(json7) // Pen(brand=Pilot, color=BLUE, price=10.0)
  • ExclusionStrategy:
    这是一个排除策略的接口,它可以让您根据一些条件来排除某些字段或类不参与序列化或反序列化。它适合处理不需要暴露或转换的敏感或无关的数据,例如带有特定注解、修饰符、名称等的字段或类。使用方法是实现这个接口,并重写shouldSkipField()和shouldSkipClass()方法,然后注册到GsonBuilder中。
gsonBuilder.setExclusionStrategies(object : ExclusionStrategy { // 设置排除策略
    override fun shouldSkipField(f: FieldAttributes): Boolean {
        return f.getAnnotation(Exclude::class.java) != null // 排除带有@Exclude注解的字段
    }

    override fun shouldSkipClass(clazz: Class<*>): Boolean {
        return false // 不排除任何类
    }
})
  • @SerializedName:这是一个用于指定字段在JSON中的名称的注解,它可以让您在序列化和反序列化时使用不同于字段名的JSON属性名。它适合处理字段名和JSON属性名不一致的情况,例如使用下划线或驼峰命名法等。使用方法是在字段上添加@SerializedName注解,并指定一个或多个JSON属性名。例如:
data class User(
    @SerializedName("user_id") val id: Int, // 在JSON中使用user_id而不是id
    @SerializedName("user_name", alternate = ["name", "username"]) val name: String // 在JSON中使用user_name,也可以接受name或username作为备选
)

  • @Expose:这是一个用于指定字段是否参与序列化和反序列化的注解,它可以让您在转换对象和JSON时忽略某些字段。它适合处理不需要暴露或转换的敏感或无关的数据,例如密码、日志、缓存等。使用方法是在字段上添加@Expose注解,并指定serialize和deserialize属性为true或false。例如:
data class User(
    @Expose(serialize = true, deserialize = true) val id: Int, // 参与序列化和反序列化
    @Expose(serialize = false, deserialize = false) val password: String, // 不参与序列化和反序列化
    @Expose(serialize = true, deserialize = false) val token: String // 只参与序列化
)

  • @Since:这是一个用于指定字段的版本号的注解,它可以让您根据不同的版本号来选择性地转换对象和JSON。它适合处理数据结构随着版本变化而变化的情况,例如添加、删除、修改字段等。使用方法是在字段上添加@Since注解,并指定一个double类型的版本号。例如:
data class User(
    @Since(1.0) val id: Int, // 从1.0版本开始存在
    @Since(1.1) val name: String, // 从1.1版本开始存在
    @Since(2.0) val email: String // 从2.0版本开始存在
)

  • @Until:这是一个用于指定字段的过期版本号的注解,它可以让您根据不同的版本号来选择性地转换对象和JSON。它适合处理数据结构随着版本变化而变化的情况,例如添加、删除、修改字段等。使用方法是在字段上添加@Until注解,并指定一个double类型的版本号。例如:
data class User(
    @Until(2.0) val id: Int, // 直到2.0版本之前存在
    @Until(3.0) val name: String, // 直到3.0版本之前存在
    val email: String // 没有过期版本号
)

整体代码

// 创建一个Gson对象
val gson = Gson()

// 创建一个表示用户的类User
data class User(
    val id: Int,
    val name: String,
    val email: String,
    val phone: String
)

// 创建一个User对象
val user = User(1, "Alice", "alice@gmail.com", "1234567890")

// 使用Gson对象的toJson()方法将User对象转换为JSON字符串
val json = gson.toJson(user) // {"id":1,"name":"Alice","email":"alice@gmail.com","phone":"1234567890"}

// 使用Gson对象的fromJson()方法将JSON字符串转换为User对象
val user2 = gson.fromJson(json, User::class.java) // User(id=1, name=Alice, email=alice@gmail.com, phone=1234567890)

// 创建一个GsonBuilder对象
val gsonBuilder = GsonBuilder()

// 使用GsonBuilder对象的各种设置方法来定制Gson的行为和特性,例如设置日期格式、排除策略、版本控制、自定义序列化和反序列化等
gsonBuilder.setDateFormat("yyyy-MM-dd") // 设置日期格式
gsonBuilder.setExclusionStrategies(object : ExclusionStrategy { // 设置排除策略
    override fun shouldSkipField(f: FieldAttributes): Boolean {
        return f.getAnnotation(Exclude::class.java) != null // 排除带有@Exclude注解的字段
    }

    override fun shouldSkipClass(clazz: Class<*>): Boolean {
        return false // 不排除任何类
    }
})
gsonBuilder.setVersion(2.0) // 设置版本控制
gsonBuilder.registerTypeAdapter(Book::class.java, object : JsonSerializer<Book> { // 注册自定义序列化器
    override fun serialize(src: Book, typeOfSrc: Type, context: JsonSerializationContext): JsonElement {
        val jsonObject = JsonObject()
        jsonObject.addProperty("id", src.id)
        jsonObject.addProperty("title", src.title.toUpperCase()) // 将标题转换为大写
        jsonObject.addProperty("author", src.author)
        return jsonObject
    }
})
gsonBuilder.registerTypeAdapter(Book::class.java, object : JsonDeserializer<Book> { // 注册自定义反序列化器
    override fun deserialize(json: JsonElement, typeOfT: Type, context: JsonDeserializationContext): Book {
        val jsonObject = json.asJsonObject
        val id = jsonObject.get("id").asInt
        val title = jsonObject.get("title").asString.toLowerCase() // 将标题转换为小写
        val author = jsonObject.get("author").asString
        return Book(id, title, author)
    }
})

// 使用GsonBuilder对象的create()方法来生成一个Gson对象
val gson2 = gsonBuilder.create()

// 使用生成的Gson对象来转换对象和JSON,根据定制的行为和特性进行转换

// 创建一个表示书籍的类Book,并使用@Since和@Until注解来指定版本号
data class Book(
    @Since(1.0) @Until(2.0) val id: Int,
    @Since(1.1) @Until(3.0) val title: String,
    val author: String
)

// 创建一个Book对象
val book = Book(1, "Kotlin in Action", "Dmitry Jemerov")

// 使用生成的Gson对象的toJson()方法将Book对象转换为JSON字符串,根据版本号来选择性地转换字段
val json2 = gson2.toJson(book) // {"title":"KOTLIN IN ACTION","author":"Dmitry Jemerov"}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Book对象,根据版本号和自定义反序列化器来选择性地转换属性
val book2 = gson2.fromJson(json2, Book::class.java) // Book(id=0, title=kotlin in action, author=Dmitry Jemerov)

// 创建一个表示日期的Date对象
val date = Date()

// 使用生成的Gson对象的toJson()方法将Date对象转换为JSON字符串,根据日期格式来转换值
val json3 = gson2.toJson(date) // "2023-04-15"

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Date对象,根据日期格式来转换值
val date2 = gson2.fromJson(json3, Date::class.java) // Sat Apr 15 00:00:00 GMT+08:00 2023

// 创建一个表示学生的类Student,并使用@SerializedName注解来指定字段在JSON中的名称
data class Student(
    @SerializedName("student_id") val id: Int,
    @SerializedName("student_name") val name: String,
    val age: Int
)

// 创建一个Student对象
val student = Student(1, "Bob", 18)

// 使用生成的Gson对象的toJson()方法将Student对象转换为JSON字符串,根据@SerializedName注解来使用不同于字段名的JSON属性名
val json4 = gson2.toJson(student) // {"student_id":1,"student_name":"Bob","age":18}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Student对象,根据@SerializedName注解来使用不同于字段名的JSON属性名
val student2 = gson2.fromJson(json4, Student::class.java) // Student(id=1, name=Bob, age=18)

// 创建一个表示员工的类Employee,并使用@Expose注解来指定字段是否参与序列化和反序列化
data class Employee(
    @Expose(serialize = true, deserialize = true) val id: Int,
    @Expose(serialize = false, deserialize = false) val password: String,
    @Expose(serialize = true, deserialize = false) val token: String
)

// 创建一个Employee对象
val employee = Employee(1, "123456", "abcdef")

// 使用生成的Gson对象的toJson()方法将Employee对象转换为JSON字符串,根据@Expose注解来忽略某些字段
val json5 = gson2.toJson(employee) // {"id":1,"token":"abcdef"}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Employee对象,根据@Expose注解来忽略某些字段
val employee2 = gson2.fromJson(json5, Employee::class.java) // Employee(id=1, password=null, token=null)

// 创建一个JsonReader对象,用于读取JSON数据
val jsonReader = JsonReader(FileReader("test.json")) // 从文件中读取JSON数据

// 使用JsonReader对象的各种读取方法,以流式的方式读取JSON数据,而不需要将整个JSON文档加载到内存中
jsonReader.beginObject() // 开始读取一个JSON对象
while (jsonReader.hasNext()) { // 循环读取每个键值对
    val name = jsonReader.nextName() // 读取键名
    when (name) { // 根据键名判断值的类型和处理逻辑
        "id" -> {
            val id = jsonReader.nextInt() // 读取整数值
            println("id: $id")
        }
        "name" -> {
            val name = jsonReader.nextString() // 读取字符串值
            println("name: $name")
        }
        "email" -> {
            val email = jsonReader.nextString() // 读取字符串值
            println("email: $email")
        }
        "phone" -> {
            val phone = jsonReader.nextString() // 读取字符串值
            println("phone: $phone")
        }
        else -> {
            jsonReader.skipValue() // 跳过其他值
        }
    }
}
jsonReader.endObject() // 结束读取一个JSON对象

// 创建一个JsonWriter对象,用于写入JSON数据
val jsonWriter = JsonWriter(FileWriter("test.json")) // 写入JSON数据到文件中

// 使用JsonWriter对象的各种写入方法,以流式的方式写入JSON数据,而不需要创建一个完整的JSON对象
jsonWriter.beginObject() // 开始写入一个JSON对象
jsonWriter.name("id").value(1) // 写入一个键值对,键名为id,值为1
jsonWriter.name("name").value("Alice") // 写入一个键值对,键名为name,值为Alice
jsonWriter.name("email").value("alice@gmail.com") // 写入一个键值对,键名为email,值为alice@gmail.com
jsonWriter.name("phone").value("1234567890") // 写入一个键值对,键名为phone,值为1234567890
jsonWriter.endObject() // 结束写



// 创建一个表示学生的类Student,并使用@SerializedName注解来指定字段在JSON中的名称
data class Student(
    @SerializedName("student_id") val id: Int,
    @SerializedName("student_name") val name: String,
    val age: Int
)

// 创建一个Student对象
val student = Student(1, "Bob", 18)

// 使用生成的Gson对象的toJson()方法将Student对象转换为JSON字符串,根据@SerializedName注解来使用不同于字段名的JSON属性名
val json4 = gson2.toJson(student) // {"student_id":1,"student_name":"Bob","age":18}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Student对象,根据@SerializedName注解来使用不同于字段名的JSON属性名
val student2 = gson2.fromJson(json4, Student::class.java) // Student(id=1, name=Bob, age=18)

// 创建一个表示员工的类Employee,并使用@Expose注解来指定字段是否参与序列化和反序列化
data class Employee(
    @Expose(serialize = true, deserialize = true) val id: Int,
    @Expose(serialize = false, deserialize = false) val password: String,
    @Expose(serialize = true, deserialize = false) val token: String
)

// 创建一个Employee对象
val employee = Employee(1, "123456", "abcdef")

// 使用生成的Gson对象的toJson()方法将Employee对象转换为JSON字符串,根据@Expose注解来忽略某些字段
val json5 = gson2.toJson(employee) // {"id":1,"token":"abcdef"}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Employee对象,根据@Expose注解来忽略某些字段
val employee2 = gson2.fromJson(json5, Employee::class.java) // Employee(id=1, password=null, token=null)

// 创建一个JsonReader对象,用于读取JSON数据
val jsonReader = JsonReader(FileReader("test.json")) // 从文件中读取JSON数据

// 使用JsonReader对象的各种读取方法,以流式的方式读取JSON数据,而不需要将整个JSON文档加载到内存中
jsonReader.beginObject() // 开始读取一个JSON对象
while (jsonReader.hasNext()) { // 循环读取每个键值对
    val name = jsonReader.nextName() // 读取键名
    when (name) { // 根据键名判断值的类型和处理逻辑
        "id" -> {
            val id = jsonReader.nextInt() // 读取整数值
            println("id: $id")
        }
        "name" -> {
            val name = jsonReader.nextString() // 读取字符串值
            println("name: $name")
        }
        "email" -> {
            val email = jsonReader.nextString() // 读取字符串值
            println("email: $email")
        }
        "phone" -> {
            val phone = jsonReader.nextString() // 读取字符串值
            println("phone: $phone")
        }
        else -> {
            jsonReader.skipValue() // 跳过其他值
        }
    }
}
jsonReader.endObject() // 结束读取一个JSON对象

// 创建一个JsonWriter对象,用于写入JSON数据
val jsonWriter = JsonWriter(FileWriter("test.json")) // 写入JSON数据到文件中

// 使用JsonWriter对象的各种写入方法,以流式的方式写入JSON数据,而不需要创建一个完整的JSON对象
jsonWriter.beginObject() // 开始写入一个JSON对象
jsonWriter.name("id").value(1) // 写入一个键值对,键名为id,值为1
jsonWriter.name("name").value("Alice") // 写入一个键值对,键名为name,值为Alice
jsonWriter.name("email").value("alice@gmail.com") // 写入一个键值对,键名为email,值为alice@gmail.com
jsonWriter.name("phone").value("1234567890") // 写入一个键值对,键名为phone,值为1234567890
jsonWriter.endObject() // 结束写入一个JSON对象

// 创建一个JsonParser对象,用于解析JSON数据
val jsonParser = JsonParser()

// 使用JsonParser对象的parse()方法来解析JSON字符串为一个JsonElement对象
val jsonElement = jsonParser.parse(json) // 解析JSON字符串为一个JsonElement对象

// 使用JsonElement对象的各种方法,将JSON数据表示为一棵树状的结构,每个节点都是一个JsonElement对象,可以是JsonObject、JsonArray、JsonPrimitive或JsonNull
if (jsonElement.isJsonObject) { // 判断是否是一个JSON对象
    val jsonObject = jsonElement.asJsonObject // 获取JSON对象
    if (jsonObject.has("id")) { // 判断是否有id属性
        val id = jsonObject.get("id").asInt // 获取id属性的值
        println("id: $id")
    }
    if (jsonObject.has("name")) { // 判断是否有name属性
        val name = jsonObject.get("name").asString // 获取name属性的值
        println("name: $name")
    }
    if (jsonObject.has("email")) { // 判断是否有email属性
        val email = jsonObject.get("email").asString // 获取email属性的值
        println("email: $email")
    }
    if (jsonObject.has("phone")) { // 判断是否有phone属性
        val phone = jsonObject.get("phone").asString // 获取phone属性的值
        println("phone: $phone")
    }
}

// 创建一个表示图书馆的类Library,并使用@Expose注解来指定字段是否参与序列化和反序列化,使用@SerializedName注解来指定字段在JSON中的名称,使用@Since和@Until注解来指定字段的版本号
data class Library(
    @Expose(serialize = true, deserialize = true) @SerializedName("library_id") @Since(1.0) @Until(2.0) val id: Int,
    @Expose(serialize = true, deserialize = true) @SerializedName("library_name") @Since(1.1) @Until(3.0) val name: String,
    @Expose(serialize = false, deserialize = false) @SerializedName("library_password") val password: String,
    @Expose(serialize = true, deserialize = false) @SerializedName("library_token") val token: String,
    val books: List<Book>
)

// 创建一个Library对象
val library = Library(1, "My Library", "123456", "abcdef", listOf(book, book2))

// 使用生成的Gson对象的toJson()方法将Library对象转换为JSON字符串,根据各种注解来定制转换过程
val json6 = gson2.toJson(library) // {"library_name":"MY LIBRARY","library_token":"abcdef","books":[{"title":"KOTLIN IN ACTION","author":"Dmitry Jemerov"}]}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Library对象,根据各种注解来定制转换过程
val library2 = gson2.fromJson(json6, Library::class.java) // Library(id=0, name=MY LIBRARY, password=null, token=null, books=[Book(id=0, title=kotlin in action, author=Dmitry Jemerov)])

// 创建一个表示颜色的枚举类Color,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
enum class Color {
    @TypeAdapter(ColorTypeAdapter::class)
    RED,
    GREEN,
    BLUE
}

// 创建一个自定义的TypeAdapter类,用于控制Color枚举类和JSON之间的转换过程
class ColorTypeAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter, value: Color) {
        out.value(value.ordinal) // 将枚举值转换为整数值写入JSON中
    }

    override fun read(`in`: JsonReader): Color {
        return Color.values()[`in`.nextInt()] // 将整数值从JSON中读取并转换为枚举值
    }
}

// 创建一个表示画笔的类Pen,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
data class Pen(
    val brand: String,
    val color: Color,
    val price: Double
) {
    @TypeAdapter(PenTypeAdapter::class)
    constructor(json: String) : this("", Color.RED, 0.0) // 使用一个带有JSON字符串参数的构造器,并使用@TypeAdapter注解来指定




// 创建一个表示颜色的枚举类Color,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
enum class Color {
    @TypeAdapter(ColorTypeAdapter::class)
    RED,
    GREEN,
    BLUE
}

// 创建一个自定义的TypeAdapter类,用于控制Color枚举类和JSON之间的转换过程
class ColorTypeAdapter : TypeAdapter<Color>() {
    override fun write(out: JsonWriter, value: Color) {
        out.value(value.ordinal) // 将枚举值转换为整数值写入JSON中
    }

    override fun read(`in`: JsonReader): Color {
        return Color.values()[`in`.nextInt()] // 将整数值从JSON中读取并转换为枚举值
    }
}

// 创建一个表示画笔的类Pen,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
data class Pen(
    val brand: String,
    val color: Color,
    val price: Double
) {
    @TypeAdapter(PenTypeAdapter::class)
    constructor(json: String) : this("", Color.RED, 0.0) // 使用一个带有JSON字符串参数的构造器,并使用@TypeAdapter注解来指定自定义的TypeAdapter类
}

// 创建一个自定义的TypeAdapter类,用于控制Pen类和JSON之间的转换过程
class PenTypeAdapter : TypeAdapter<Pen>() {
    override fun write(out: JsonWriter, value: Pen) {
        out.beginObject() // 开始写入一个JSON对象
        out.name("brand").value(value.brand) // 写入一个键值对,键名为brand,值为画笔品牌
        out.name("color").value(value.color.ordinal) // 写入一个键值对,键名为color,值为画笔颜色对应的整数值
        out.name("price").value(value.price) // 写入一个键值对,键名为price,值为画笔价格
        out.endObject() // 结束写入一个JSON对象
    }

    override fun read(`in`: JsonReader): Pen {
        var brand = ""
        var color = Color.RED
        var price = 0.0
        `in`.beginObject() // 开始读取一个JSON对象
        while (`in`.hasNext()) { // 循环读取每个键值对
            val name = `in`.nextName() // 读取键名
            when (name) { // 根据键名判断值的类型和处理逻辑
                "brand" -> {
                    brand = `in`.nextString() // 读取字符串值作为画笔品牌
                }
                "color" -> {
                    color = Color.values()[`in`.nextInt()] // 读取整数值并转换为画笔颜色对应的枚举值
                }
                "price" -> {
                    price = `in`.nextDouble() // 读取浮点数值作为画笔价格
                }
                else -> {
                    `in`.skipValue() // 跳过其他值
                }
            }
        }
        `in`.endObject() // 结束读取一个JSON对象
        return Pen(brand, color, price) // 返回一个Pen对象
    }
}

// 创建一个Pen对象
val pen = Pen("Pilot", Color.BLUE, 10.0)

// 使用生成的Gson对象的toJson()方法将Pen对象转换为JSON字符串,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val json7 = gson2.toJson(pen) // {"brand":"Pilot","color":2,"price":10.0}

// 使用生成的Gson对象的fromJson()方法将JSON字符串转换为Pen对象,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val pen2 = gson2.fromJson(json7, Pen::class.java) // Pen(brand=Pilot, color=BLUE, price=10.0)

// 使用带有JSON字符串参数的构造器来创建一个Pen对象,根据@TypeAdapter注解和自定义的TypeAdapter类来控制转换过程
val pen3 = Pen(json7) // Pen(brand=Pilot, color=BLUE, price=10.0)
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,233评论 6 495
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,357评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,831评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,313评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,417评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,470评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,482评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,265评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,708评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,997评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,176评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,827评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,503评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,150评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,391评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,034评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,063评论 2 352

推荐阅读更多精彩内容

  • 转自:http://www.jianshu.com/p/3108f1e44155?nomobile=yes 该系列...
    逍遥游lx阅读 1,140评论 0 2
  • 1.概述2.Gson的目标3.Gson的性能和扩展性4.Gson的使用者5.如何使用Gson 通过Maven来使用...
    人失格阅读 14,227评论 2 18
  • 本文为作者根据日常使用结合Gson源码注释及wiki所作的原创内容,转载请注明出处。 该系列其它文章 你真的会用G...
    怪盗kidou阅读 78,245评论 119 213
  • Json 是一种文本形式的数据交换格式,比 xml 更为轻量。Json 的解析和生成的方式很多,在 Android...
    业志陈阅读 79,118评论 9 69
  • 概况 Gson是一个Java库,它可以用来把Java对象转换为JSON表达式,也可以反过来把JSON字符串转换成与...
    木豚阅读 6,784评论 0 2