子类重写equals方法时必须调用super.equals(obj),否则父类字段未参与比较会导致逻辑相等的对象返回false;且传参须为原始obj而非转型对象,同时hashCode也需包含super.hashCode()以保证一致性。

子类重写 equals 方法时漏掉父类属性,最直接的后果是:两个本该逻辑相等的对象(父类字段相同、子类字段也相同)却返回 false。这不是疏忽,而是继承语义被破坏——子类对象的“相等性”必须包含父类定义的身份基础。
必须调用 super.equals(obj)
这是避免遗漏的强制动作,不是可选项:
- 父类中参与判等的字段(如
id、code、name)由父类自己的equals实现负责校验,子类无需、也不应重复比较 - 调用
super.equals(obj)前,父类内部已做完空值检查、类型校验(getClass() == obj.getClass())、以及它自身字段的Objects.equals比较 - 如果跳过这一步,哪怕子类字段全匹配,只要父类字段有差异或未参与比较,结果就是不等
传参必须是原始 obj,不是转型后的对象
常见错误写法:
SubClass that = (SubClass) obj; if (!super.equals(that)) return false; // ❌ 错!父类 getClass() 校验会失败
正确写法:
当用户要求为 Java 代码添加注释、修改注释、审查注释、整理注释格式,或要求按照代码注释规范处理 Java 文件时,使用本技能。本技能用于统一生成和维护 Java 类注释模板、按 Git 对比 release 判断版本号、补充每行代码上方中文块注释、调整注释空行规则,并保持 Java 文件 UTF-8 无 BOM 编码。典型触发场景包括:补充类注释、更新 @version、检查 @author 来源、整理行尾注释、把注释放到代码上一行、检查注释是否符合规范、构建前检查 Java 注释风格。
立即学习“Java免费学习笔记(深入)”;
if (!super.equals(obj)) return false; // ✅ 对!让父类自己做类型转换和字段比对
因为父类 equals 内部依赖 getClass() 判断,若传入已转型的 that,其运行时类型仍是 SubClass,但父类期望接收的是原始参数并自行强转——传错对象会导致类型校验误判或 ClassCastException。
只扩展自有字段,不碰父类逻辑
子类职责明确:在父类确认“身份一致”的前提下,再叠加业务特有维度:
- 父类字段(如
id、status)已在super.equals(obj)中覆盖 - 子类新增字段(如
radius、color、tags)用Objects.equals(this.field, that.field)单独比较 - 禁止在子类
equals中重新比较父类字段(比如又写一遍Objects.equals(id, that.id)),否则既冗余,又可能因顺序/逻辑不一致引发矛盾
配套检查 hashCode 是否同步更新
漏掉父类字段不仅影响 equals,更会拖垮 hashCode:
- 如果
super.equals(obj)返回true,说明父类字段相等;那么hashCode必须包含这些字段的哈希值 - 子类重写
hashCode时,推荐写法:return Objects.hash(super.hashCode(), radius, color); - 若只写
Objects.hash(radius, color),而忽略super.hashCode(),两个父类字段不同但子类字段相同的对象可能产生相同哈希码,违反契约

















