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

In Kotlin, how does GSON.fromJson(...) manage to mutate a read-only field of an existing object?

在 Kotlin 中,如何修改实例的只读 val 字段?

在下面的 Kotlin 代码中,gson.fromJson(...)InstanceCreator 得到一个 Thing(0) 并以某种方式设法将 value0 突变为 1,然后 return 该对象。怎么样?

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(...) 编辑的对象 return 与 InstanceCreator 提供的对象相同,因此它不会根据 InstanceCreator 提供的对象创建新实例=15=].

我也试过用反射设置value,但是没有找到方法。 val 字段中没有可用的 setter。

I also tried setting value using reflection

嗯,如果你使用 Java 的反射 API,而不是 Kotlin 的反射,你就可以做到。

Kotlin val 属性转换为只有 public getter 的私有 Java 字段。您可以使用反射设置私有字段。例如:

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

这可能也是 Gson 在幕后所做的。