You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin使用==比较data class时类内属性是否参与相等判断

结论

你的理解完全正确,这段断言会错误通过,两个实例的name字段差异根本没被==校验到,是Kotlin语言特性和Gson库机制叠加导致的结果。


原因说明

1. Kotlin data class 的相等判断逻辑

Kotlin 里data class自动生成的equals()(也就是==操作符实际调用的方法)、hashCode()、copy()这些方法,只会将主构造函数中声明的属性纳入计算范围,定义在类体内部的属性不会参与这些自动生成的逻辑。
你定义的X类主构造里只有isThatSo: Boolean一个属性,类体里写的name属于类内部成员,自动生成的相等判断完全不会校验它的值,只要两个实例的isThatSo一致,==就会返回true。

data class X(val isThatSo: Boolean) {
  val name:String = "xyz"
}

哪怕两个实例的name值一个是"Ankit"一个是"xyz",只要isThatSo都是true,比较结果就是相等。

2. Gson 反序列化Kotlin类的固有问题

Gson 是原生为Java设计的序列化库,本身不识别Kotlin的主构造函数、属性默认值、空安全等语法特性:

  • 反序列化时Gson不会调用类的主构造方法,而是通过底层Unsafe接口直接分配内存创建空实例,再通过反射把JSON里的字段值挨个注入对象
  • 你提供的JSON中包含"name": "Ankit"字段,Gson会直接通过反射把这个值写入实例的name属性,完全无视这个属性不在主构造、有预设默认值的设定
  • 如果JSON中缺失某个字段,Gson会直接给对应字段赋Java类型的默认零值:对象类型赋值null、布尔类型赋值false、数值类型赋值0,你在代码里写的默认值逻辑根本不会触发。
    你测试代码里JSON把isThatSo的值写成字符串"true"也能正常反序列化,也是Gson默认做了宽松类型转换的结果,不影响核心判断逻辑。

修复方式
  • 把需要参与相等判断、需要默认值生效的属性全部挪到data class的主构造函数中:
data class X(
  val isThatSo: Boolean,
  val name: String = "xyz"
)

修改后自动生成的equals方法会把name纳入校验,两个实例name不一致时==就会正确返回false。

  • 尽量不要用原生Gson反序列化Kotlin data class,优先选择对Kotlin有原生支持的序列化实现,比如kotlinx.serialization、带Kotlin代码生成适配的Moshi;如果必须使用Gson,需要额外接入对应的Kotlin适配适配器,避免绕过构造函数的问题。

内容的提问来源于stack exchange,提问作者Ankit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 11:03:15