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

Kotlin中判断sealed class对象同类型及object作为Map key取值null问题

问题根因分析

Kotlin中object声明的类默认是JVM单例的前提是由同一个类加载器加载,且没有经过序列化/反序列化、反射强制构造等操作。你遇到的多实例场景,大概率是不同模块使用了独立的类加载器加载SealedClass类,或者Pizza对象经历了序列化/反序列化流程,才生成了多个不同引用的实例。默认object的equals方法是引用相等判断,所以两个不同实例作为Map的key时会被判定为不同键,导致取值返回null。

实现Pizza实例作为key可统一取值的方案

方案1:单独给Pizza重写equals和hashcode(轻量改法)

如果你不想修改父类和其他子类的原有逻辑,直接给Pizza单例单独重写相等判断规则即可:

sealed class SealedClass {
  object Pizza: SealedClass() {
    override fun equals(other: Any?): Boolean {
      return other is Pizza
    }

    override fun hashCode(): Int {
      return this::class.hashCode()
    }
  }
  data class Hamburger(val hasCheese: Boolean): SealedClass()
}

修改后只要是Pizza类型的实例,不管引用是否相同,都会被判定为相等,作为Map的key可以正常取值,Hamburger作为data class默认的属性相等判断逻辑不受影响。

方案2:统一重写父类的equals和hashcode(推荐)

如果后续还要新增sealed类的子类,可以统一在父类中定义相等规则,避免后续重复修改:

sealed class SealedClass {
  object Pizza: SealedClass()
  data class Hamburger(val hasCheese: Boolean): SealedClass()

  override fun equals(other: Any?): Boolean {
    if (this === other) return true
    if (javaClass != other?.javaClass) return false
    return when (this) {
      is Pizza -> true
      is Hamburger -> hasCheese == (other as Hamburger).hasCheese
    }
  }

  override fun hashCode(): Int {
    return when (this) {
      is Pizza -> javaClass.hashCode()
      is Hamburger -> 31 * javaClass.hashCode() + hasCheese.hashCode()
    }
  }
}

方案3:从根源避免生成多实例

如果是序列化导致的多实例问题,可以给Pizza单例添加readResolve方法,反序列化时强制返回全局单例:

object Pizza: SealedClass() {
  private fun readResolve(): Any = Pizza
}

如果是类加载器导致的问题,调整模块的类加载策略,保证SealedClass由同一个类加载器加载即可。

两个sealed class对象的同类型判断方法
  • 同类加载器场景:直接比较::class属性即可,示例:obj1::class == obj2::class
  • 跨类加载器场景:比较类的全限定名,示例:obj1.javaClass.name == obj2.javaClass.name
  • 单一类型判断:直接使用is关键字,示例:if (obj is SealedClass.Pizza) { /* 是Pizza类型 */ }

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:57:03