在Kotlin中,GSON.fromJson(...)是如何改变现有对象的只读字段的?

r1wp621o  于 2022-11-06  发布在  Kotlin
关注(0)|答案(1)|浏览(173)

在Kotlin中,如何改变示例的只读val字段?
在下面的Kotlin代码中,gson.fromJson(...)InstanceCreator得到一个Thing(0),然后设法将value0突变为1,然后返回该对象。如何实现?

import com.google.gson.GsonBuilder
import com.google.gson.InstanceCreator

class Thing(val value: Int)

fun main() {
    val creator = InstanceCreator { Thing(0) }
    val gson = GsonBuilder().registerTypeAdapter(Thing::class.java, creator).create()
    val thing = gson.fromJson("""{"value":1}""", Thing::class.java)
    println(thing.value) // 1
}

我验证了gson.fromJson(...)返回的对象与InstanceCreator提供的对象相同,因此它不会基于InstanceCreator提供的对象创建新示例。
我也尝试过使用反射来设置value,但是没有找到方法。val字段上没有可用的setter。

u7up0aaq

u7up0aaq1#

我还尝试使用反射设置值
如果使用Java的反射API而不是Kotlin的API,就可以做到这一点。
Kotlinval属性转换为只有公共getter的私有Java字段。您可以使用反射设置私有字段。例如:

val x = Thing(10)
val valueField = x.javaClass.getDeclaredField("value")
valueField.trySetAccessible()
valueField.setInt(x, 20)
println(x.value)

这可能也是Gson在引擎盖下做的事情。

相关问题