JAVA 对象语义实验

equals 与 hashCode 契约实验室

== 回答“是不是同一个对象”,equals 回答“按当前业务规则是否相等”。当值相等参与哈希集合时,hashCode 必须与它保持一致。

相等对象 → 必须同哈希 同哈希 ⇏ 一定相等 身份字段宜保持不可变

一、实时比较台

规范化规则固定为 trim().toUpperCase();它只是本例的业务规则,不是 Java 自动执行的行为。

选择对象的相等策略

三个 Sku 值对象

对象 A ref#A
规范化
SKU-07
hashCode
对象 B ref#B
规范化
SKU-07
hashCode
对象 C ref#C
规范化
SKU-99
hashCode

比较结果

对象对==equals哈希相同

二、契约检查器

检查器基于当前 A、B、C 样本。当前没有触发某个前提时,会明确显示“未触发”,而不是伪装成充分证明。

三、可变身份字段风险

这里故意允许修改 A 的 code,以观察为什么用于相等与哈希的身份字段通常应保持不可变。

简化哈希集合实验

先记录 A 加入时的哈希入口,再修改上方 A 的 code,最后用 A 当前的哈希尝试查找。

加入时记录的哈希入口 尚未加入
查找时由 A 当前状态得到
请先将 A 加入模拟集合。

四、三道契约挑战

挑战 1 A 与 B 引用不同,但规范化 code 都是 SKU-07。正确重写时结果是?
挑战 2 关于 equalshashCode,哪项准确?
挑战 3 对象已加入哈希集合,参与哈希的 code 需要变化,优先怎样设计?
带走这一句:先定义“业务上何时算同一个值”,再让 equalshashCode 使用一致、稳定的身份;== 仍只负责回答引用身份。