【发布时间】:2013-04-10 11:46:03
【问题描述】:
没有人真正谈论过 equals() 和 hasCode() 的这一方面,但对 equals() 和hashCode() 行为。在处理引用其他对象的更复杂的对象时非常庞大。
Joshua Bloch 在他的 Effective Java 中甚至没有在他的“覆盖 equals() 方法”一章中提到它。他所有的例子都是像 Point 和 ColorPoint 这样的琐事,都只有原始或接近原始的类型。
可以避免递归吗?有时几乎没有。假设:
Person {
String name;
Address address;
}
这两个字段都必须转到 business key(正如 Hibernate 人所说),它们都是 value components(正如 Joshua Bloch 所说)。 Address 本身就是一个复杂的对象。递归。
请注意,Eclipse 和 IntelliJ 等 IDE 确实会生成递归 equals() 和 hashCode()。 默认情况下,它们使用所有字段。如果你大量使用生成器工具,你就是在自找麻烦。
一个麻烦是你会得到一个StackOverflowError。这是我的simple test proving it。
所需要的只是将另一个对象作为“值组件”的类,形成一个对象图和推荐的 equals() 实现。是的,您需要在该循环中绘制图表,但这并非不切实际(想象分子、地图上的路径、相互关联的交易......)。
另一个问题是性能。 equals() 推荐的实际上是比较两个对象图,可能是巨大的图,最终可能会在不知情的情况下比较数千个节点。并不是所有的都在内存中是必需的!考虑到某些对象可能是可延迟加载的。一个 equals() 或 hashCode() 调用最终可能会加载一半的数据库。
悖论是,你越是严格地重写 equals() 和 hashCode(),你就越有可能遇到麻烦。
【问题讨论】: