Kotlin 我们能否依赖Gson';s修改val属性的能力?

Kotlin 我们能否依赖Gson';s修改val属性的能力?,kotlin,gson,immutability,Kotlin,Gson,Immutability,Kotlin的val属性在设计上是不变的。在初始化之后,它们应该是固定不变的 然而,我意外地发现,Gson能够修改这些属性 考虑这个例子: //Entity class: class User { val name: String = "" val age: Int = 0 } 由于名称和年龄被定义为val,并被初始化为空字符串和零,因此它们必须保持不变且永不更改 但是,此测试成功: fun main() { val json = "{\"name\":\"Mousa\

Kotlin的
val
属性在设计上是不变的。在初始化之后,它们应该是固定不变的

然而,我意外地发现,
Gson
能够修改这些属性

考虑这个例子:

//Entity class:
class User {
    val name: String = ""
    val age: Int = 0
}
由于
名称
年龄
被定义为
val
,并被初始化为空字符串和零,因此它们必须保持不变且永不更改

但是,此测试成功:

fun main() {
    val json = "{\"name\":\"Mousa\",\"age\":30}"
    val user = Gson().fromJson<User>(json, User::class.java)
    assert(user.name == "Mousa")
    assert(user.age == 30)
    print("Success")
}
fun main(){
val json=“{\'name\':\'Mousa\',\'age\':30}”
val user=Gson().fromJson(json,user::class.java)
断言(user.name==“Mousa”)
断言(user.age==30)
打印(“成功”)
}
使用此功能可以使代码更干净。因为这些属性是由Gson修改的,不能由代码的其余部分修改。否则,我需要为Gson提供一些可变的支持字段,并为代码的其余部分提供一些不可变的属性


我不知道这是Gson的“功能”还是“缺陷”。所以我的问题是:我们可以依赖它吗,或者这种行为以后可能会改变?

如果运行
javap-p User.class
,您会得到以下输出:

public final class q54491286.User {
    private final java.lang.String name;
    private final int age;
    public final java.lang.String getName();
    public final int getAge();
    public q54491286.User();
}
Kotlin不变性是由(隐式地)声明为
private
final
的字段生成的无突变子方法支持的。 除非定义自定义类型适配器,否则Gson在序列化和反序列化普通数据对象类期间(请参阅“使用字段vs getter指示Json元素”一节中的更多内容),在设计上不会分别使用访问器和变异器。 此外,Gson还可以修改
最终
字段,这也是一种设计选择

由于大量使用反射,不变性在Java中是相对的。 例如,我可以使用反射轻松修改不可变(按设计)字符串,使其成为某种可变(按设计):

最终字符串s=“foo”;
最终字段valueField=String.class.getDeclaredField(“值”);
valueField.setAccessible(true);
集合(s,新字符[]{'b','a','r'});
系统输出打印项次;
当使用
java版本“1.8.0_191”
中的我的
java
时,会产生
bar
。 没有不变性,他

另一方面,如果Gson类型适配器策略以通用方式重新定义方法(Gson禁止重新定义
Object
JsonElement
类型适配器)可以检测到您的类,那么您就可以编写一个自定义反序列化器来禁止Kotlin生成的类(由
kotlin.Metadata
注释检测到)只读字段被反序列化(但不确定是否有好处)。 或者只需实现一个反序列化器,该反序列化器将扫描JSON流/树中的非只读字段,并仅在构造新的
User
对象时使用它们,其合法构造函数不使用反射

我不知道这是Gson的“功能”还是“Bug”

总而言之,这是一个特色

所以我的问题是:我们能依靠这个吗,或者这种行为以后可能会改变

这很可能在Gson 2.x中永远不会改变。
据我所知,目前还没有发布主要更新的计划,如Gson 3.x等。

感谢您提供了完整的回答。欢迎访问。