Kotlin 序列化 @SerialName 不适用于布尔值

TJ *_*sen 2 serialization android gson kotlin

我正在使用 GSON 序列化一些平台数据。当我@SerialName在应用程序中使用不同的命名约定捕获平台数据时,它适用于其他类型,但不适用于Boolean类型。举一个简单的例子,如果我有一个像这样的课程......

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class Person (
    @SerialName("first_name") val firstName: String? = null,
    @SerialName("last_name") val lastName: String? = null,
    val age: Int? = null
)
Run Code Online (Sandbox Code Playgroud)

...一切正常。序列化器在数据中查找,first_name并正确设置.last_nameagePerson

但是,当我尝试添加Boolean...

import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

@Serializable
data class Person (
    @SerialName("first_name") val firstName: String? = null,
    @SerialName("last_name") val lastName: String? = null,
    val age: Int? = null,
    @SerialName("can_sing") val canSing: Boolean? = null
)
Run Code Online (Sandbox Code Playgroud)

...序列化器不会捕获和分配can_sing。奇怪的是它适用于 aString但不适用于 a Boolean。任何人都可以解释为什么我会看到这种行为吗?我可以解决这个问题(例如,我可以做到val can_sing: Boolean? = null并且它有效),但我只是想知道为什么@SerialName似乎不适用于 a Boolean,或者如果我只是错过了一些明显的东西。

Tyl*_*r V 5

您正在混合 Gson 和 Kotlin 注释类型 - Gson 使用@SerializedNamenot @SerialName。我不确定您的字符串类型在这种情况下如何工作(也许您如何调用 Gson 的方式未包含在问题中)。

例如,这里的第一个类 ( Person) 可以使用 Kotlin 序列化库进行序列化,第二个类可以使用 Gson 进行序列化:

Kotlin 注释

@Serializable
data class Person (
    @SerialName("first_name") val firstName: String? = null,
    @SerialName("last_name") val lastName: String? = null,
    val age: Int? = null,
    @SerialName("can_sing") val canSing: Boolean? = null
)
Run Code Online (Sandbox Code Playgroud)

Gson注解

data class PersonGson (
    @SerializedName("first_name") val firstName: String? = null,
    @SerializedName("last_name") val lastName: String? = null,
    val age: Int? = null,
    @SerializedName("can_sing") val canSing: Boolean? = null
)
Run Code Online (Sandbox Code Playgroud)

例子

使用 Kotlin 序列化库运行此单元测试:

@Test
fun testJsonKotlin()  {
    val test = Person("hello", "world", 42, false)
    val json = Json.encodeToString(test)
    println(json)
    val t2 = Json.decodeFromString<Person>(json)
    println(t2)
}
Run Code Online (Sandbox Code Playgroud)

产生预期的输出:

{"first_name":"hello","last_name":"world","age":42,"can_sing":false}
Person(firstName=hello, lastName=world, age=42, canSing=false)
Run Code Online (Sandbox Code Playgroud)

用 Gson 来做这件事

{"first_name":"hello","last_name":"world","age":42,"can_sing":false}
Person(firstName=hello, lastName=world, age=42, canSing=false)
Run Code Online (Sandbox Code Playgroud)

技术上可行,但忽略序列化名称注释(对于所有情况,不仅仅是布尔值)

{"firstName":"hello","lastName":"world","age":42,"canSing":false}
Person(firstName=hello, lastName=world, age=42, canSing=false)
Run Code Online (Sandbox Code Playgroud)

将 Gson 注解的类与 Gson 一起使用

@Test
fun testJsonGson()  {
    val test = PersonGson("hello", "world", 42, false)
    val json = Gson().toJson(test)
    println(json)
    val t2 = Gson().fromJson(json, PersonGson::class.java)
    println(t2)
}
Run Code Online (Sandbox Code Playgroud)

再次给出正确的响应

{"first_name":"hello","last_name":"world","age":42,"can_sing":false}
PersonGson(firstName=hello, lastName=world, age=42, canSing=false)
Run Code Online (Sandbox Code Playgroud)