处理多个对象实例的最佳方法
部分原因是我不能在Kotlin中创建没有参数的数据类,所以我使用object
s来处理这些情况,例如
sealed class Node { object Leaf : Node() data class Branch(val left:Node, val right:Node) : Node() }
问题是,有时候,我最终得到了Leaf
类的多个实例。 显然这不应该普遍发生,但是在使用一些框架和一些测试用例序列化和反序列化时会发生这种情况。
现在,你可能会争辩说我应该修正这些情况,但是很难知道它们可能在哪里,而不总是可能或者不希望修改框架的反序列化语义。
因此,我希望我的object
的所有实例的行为都是相同的值,就像无参数data class
(或Scala中的无参数的case class
)一样。
到目前为止,我的最佳解决方案是以下内容,包括在我创建的每个可能遇到此问题的对象中:
object SaneLeaf { override fun hashCode() = javaClass.hashCode() override fun equals(other: Any?) = other?.javaClass == javaClass }
很明显,这是冗长而且容易出错的,因为把这些实现抽象到一个接口似乎是不可能的。 如果对象不需要扩展另一个类,那么超类就可以工作,但情况往往不是这样。
或者,我可以用Nothing
参数创建一个数据类。 但是,这似乎更像是一个黑客。
别人怎么处理这个问题呢? 是否有计划添加hashCode
和equals
实现对象的假定这些类的语义(所有实例应该是相同/相同的hashCode)?
我相信有一个object
的底层类的多个实例真的是一个问题,你应该修复,但有一个更简单的解决方法,让你有你描述的平等语义。
你可以定义一个执行相等逻辑的抽象类,并使sealed
类inheritance它,如下所示:
abstract class SingletonEquality { override fun equals(other: Any?): Boolean = this::class.objectInstance != null && other?.javaClass == this.javaClass || super.equals(other) override fun hashCode(): Int = if (this::class.objectInstance != null) javaClass.hashCode() else super.hashCode() }
用法:
sealed class Node : SingletonEquality() { object Leaf : Node() data class Branch(val left:Node, val right:Node) : Node() }
在这里, Leaf
将从SingletonEquality
inheritanceequals
实现,并按照你想要的方式进行比较。