使用GSON进行Kotlin对象反序列化

5
我有一个类
class ThreadComment(
    banned: Int,
    closed: Int,
    comment: String?,
    date: String?,
    email: String?,
    files: ArrayList<File>?,
    lasthit: Int,
    name: String?,
    num: String?,
    op: Int,
    parent: String?,
    postsCount: Int,
    sticky: Int,
    subject: String?,
    tags: String?,
    timestamp: Int,
    trip: String?) : Comment(banned, closed, comment, date, email, files, lasthit, name, num, op, parent, postsCount, sticky, subject, tags, timestamp, trip) {

val answers: ArrayList<String> = ArrayList()}

父类看起来像

open class Comment(
    @com.google.gson.annotations.SerializedName("banned")
    val banned: Int = 0,

    @com.google.gson.annotations.SerializedName("closed")
    val closed: Int = 0,

    @com.google.gson.annotations.SerializedName("comment")
    val comment: String? = null,

    @com.google.gson.annotations.SerializedName("date")
    val date: String? = null,

    @com.google.gson.annotations.SerializedName("email")
    val email: String? = null,

    @com.google.gson.annotations.SerializedName("files")
    val files: ArrayList<File>? = null,

    @com.google.gson.annotations.SerializedName("lasthit")
    val lasthit: Int = 0,

    @com.google.gson.annotations.SerializedName("name")
    val name: String? = null,

    @com.google.gson.annotations.SerializedName("num")
    val num: String? = null,

    @com.google.gson.annotations.SerializedName("op")
    val op: Int = 0,

    @com.google.gson.annotations.SerializedName("parent")
    val parent: String? = null,

    @com.google.gson.annotations.SerializedName("posts_count")
    val postsCount: Int = 0,

    @com.google.gson.annotations.SerializedName("sticky")
    val sticky: Int = 0,

    @com.google.gson.annotations.SerializedName("subject")
    val subject: String? = null,

    @com.google.gson.annotations.SerializedName("tags")
    val tags: String? = null,

    @com.google.gson.annotations.SerializedName("timestamp")
    val timestamp: Int = 0,

    @com.google.gson.annotations.SerializedName("trip")
    val trip: String? = null) : Serializable

但是使用GSON反序列化后,answers字段为空。 Debugger 我还尝试将初始化代码放入init{}中,但它仍然为空。使用lazy会抛出一个关于在空对象引用上调用lazy.getValue的异常。

请展示一下 JSON。 - miensol
@miensol,JSON对象不包含"answers"字段。但我也尝试使用ExclusionStrategy来进行序列化和反序列化以排除该字段。 - Ufkoku
一个小提示:Jackson(JSON deser)通过 https://github.com/FasterXML/jackson-module-kotlin 支持Kotlin构造函数和用例...对于其他Java库,您应该检查是否有类似的支持,因为它们不理解所有Kotlin概念,也无法利用它们。否则,您最终会做出不自然的Kotlin代码(例如@miensol的答案),只是为了满足您的deser库。不幸的是,GSON在可扩展性方面不够友好,无法更好地支持Kotlin。 - Jayson Minard
2个回答

9

很奇怪,我只是像在Java中使用数据类一样正常使用了@SerializedName,它就起作用了:

data class(@SerializedName("my_string_value") val myStringValue: String, @SerializedName("my_int_value") val myIntValue: Int)

8
此答案所述,Gson可以“不安全地”处理无参数构造函数场景。它通过利用UnsafeAllocator来实现,后者又使用allocateInstance(Class p)。这意味着当没有无参数构造函数并且没有自定义instance creator注册时,由Gson创建的对象将使用其声明类型的默认值初始化字段

要解决这个问题,请添加一个无参构造函数,例如:

private constructor() : this(-1, -1, "", "", "", null, -1, "", "", -1, null, -1, -1, null, null, -1, null)

或者像这样在主构造函数中添加默认参数值:

class ThreadComment(
        banned: Int = -1,
        closed: Int = -1,
        comment: String? = null,
        date: String? = null,
        email: String? = null,
        files: ArrayList<File>? = null,
        lasthit: Int = -1,
        name: String? = null,
        num: String? = null,
        op: Int = -1,
        parent: String? = null,
        postsCount: Int = -1,
        sticky: Int = -1,
        subject: String? = null,
        tags: String? = null,
        timestamp: Int = -1,
        trip: String? = null
) : Comment(banned, closed, comment, date, email, files, lasthit, name, num, op, parent, postsCount, sticky, subject, tags, timestamp, trip) {
    val answers: ArrayList<String> = ArrayList()
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接