当我创建Object时,我的初始化程序块工作得非常好
class ObjectToDeserialize(var someString: String = "") : Serializable {
init{
someString += " initialized"
}
}
这样:
@Test
fun createObject_checkIfInitialized() {
assertEquals("someString initialized",ObjectToDeserialize("someString").someString)
}
但是,当我用Gson反序列化对象时,初始化程序块没有得到执行:
@Test
fun deserializeObject_checkIfInitialized(){
val someJson: String = "{\"someString\":\"someString\" }"
val jsonObject = Gson().fromJson(someJson, ObjectToDeserialize::class.java)
assertEquals("someString initialized",jsonObject.someString)
// Expected :someString initialized
// Actual :someString
}
我认为gson创建对象的方式与执行主构造函数的方式不同,但是否有可能有类似的初始化程序块?
2条答案
按热度按时间dzhpxtsq1#
Gson是为纯Java设计的,不能正确解释Kotlin主构造函数。
如果有默认的无参数构造函数,则调用它(在您的示例中,有一个:主构造函数,默认值为
someString
),otherwise Gson calls no constructor at all。然后Gson设置属性值(同时,它绕过Kotlin属性的实际设置者,直接设置字段,这有时可能导致意外行为)。
作为一种替代方法,您可以使用jackson-module-kotlin,它在您的情况下应该能很好地工作(它理解Kotlin主构造函数,使用Kotlin设置器,并且自
2.8.x
以来也支持默认参数值)。此示例比较了jackson-module-Kotlin和Kotson的行为:
输出为
inn6fuwd2#
我在Gson中遇到了类似的问题。我的数据类有一些序列化参数和一些非序列化参数。我想让我的非序列化参数具有默认值。我找到的最简单的解决方案是让我的非序列化参数成为可选的。下面是我的解决方法: