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

Lombok中callSuper=true时继承类equals与hashCode方法未正常匹配的原因咨询

问题分析:Lombok @EqualsAndHashCode(callSuper=true) 在继承结构中不生效的原因

首先,我们来拆解你遇到的核心问题:当你把单一类拆分为继承结构后,使用@EqualsAndHashCode(callSuper=true)时,属性完全一致的子类实例却无法通过equals校验,且hashCode不相等;但callSuper=false时表现正常。

根本原因:父类未生成正确的equals/hashCode方法

你的父类EntityOne仅使用了@Getter、@Setter、@SuperBuilder等注解,但没有添加@EqualsAndHashCode或@Data注解。这意味着:

  • Lombok不会为父类生成自定义的equals和hashCode方法
  • 当子类调用super.equals()和super.hashCode()时,实际上调用的是Object类的默认实现:
    • Object.equals()仅判断两个对象是否为同一引用(内存地址相同)
    • Object.hashCode()返回的是对象的内存地址哈希值

哪怕父类的所有属性完全一致,两个不同的父类实例(子类实例的父类部分)的super.hashCode()也会不同,进而导致子类的整体hashCode不相等;equals判断时,第一步super.equals(other)就会返回false,直接导致整个判断失败。

而你在单一类EntityCombined中使用了@Data注解,它包含@EqualsAndHashCode,Lombok会生成考虑所有属性的equals和hashCode,所以表现符合预期。

为什么callSuper=false时表现正常?

当callSuper=false时,Lombok生成的子类equals和hashCode仅考虑子类自己的属性(也就是你的EntityTwo中的p字段)。你创建的测试实例中p都是默认的null,所以equals返回true、hashCode相等;当p属性不同时,判断失败,这完全符合callSuper=false的设计逻辑。

解决方案:为父类添加@EqualsAndHashCode注解

要让callSuper=true生效,你需要让父类拥有自己的、基于属性的equals和hashCode实现。只需给EntityOne添加@EqualsAndHashCode注解即可:

@AllArgsConstructor 
@NoArgsConstructor 
@Getter 
@Setter 
@SuperBuilder
@EqualsAndHashCode // 新增这个注解
public class EntityOne {
    // 原有属性和枚举代码不变
}

如果父类适合用@Data(比如不需要自定义构造器逻辑),也可以直接替换为@Data(@Data包含@EqualsAndHashCode、@Getter、@Setter等),注意调整构造器注解的冲突(@Data会生成@RequiredArgsConstructor,如果需要无参和全参构造器,仍需保留@NoArgsConstructor和@AllArgsConstructor):

@NoArgsConstructor 
@AllArgsConstructor
@Data 
@SuperBuilder
public class EntityOne {
    // 原有属性和枚举代码不变
}

添加后,子类调用super.equals()时,会使用父类生成的、基于属性的判断逻辑,结合子类自己的属性校验,就能像单一类那样实现正确的equals和hashCode判断了。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 13:47:40