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

子类继承泛型父类后equals/hashCode异常,父类ID字段为null问题排查

问题分析与解决方案

问题根源

你在子类ChildEntity中重复定义了id字段,这会隐藏父类ParentEntity中的id字段。当你通过@AllArgsConstructor生成的构造函数给子类的id赋值时,父类的id字段完全没被设置,始终为null。而你的equals和hashCode方法是基于父类的id实现的,所有实例比较时都是对比两个null,因此结果全部返回true。

解决方案

核心是删除子类中重复的id字段,让子类直接继承父类的id,并确保父类的id能被正确赋值。

步骤1:修正父类(可选,优化构造方式)

给父类添加带参构造函数,方便子类直接调用赋值:

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public abstract class ParentEntity<ID> {
    private ID id;

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ParentEntity<?> that = (ParentEntity<?>) o;
        return Objects.equals(id, that.id);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }
}

步骤2:修正子类

删除重复的id字段,手动编写全参构造函数调用父类的带参构造:

@Getter
@Setter
@NoArgsConstructor
public class ChildEntity extends ParentEntity<Long> {
    private String name;

    // 手动编写全参构造,调用父类构造赋值id
    public ChildEntity(Long id, String name) {
        super(id);
        this.name = name;
    }
}

验证结果

此时再运行测试代码:

ChildEntity childEntity = new ChildEntity(4L, "Cheese");
ChildEntity childEntity1 = new ChildEntity(4L, "Bread");
ChildEntity childEntity2 = new ChildEntity(1L, "Milk");

System.out.println(childEntity.equals(childEntity1)); // output true
System.out.println(childEntity.equals(childEntity2)); // output false

结果会符合预期:同ID实例返回true,不同ID返回false。

关键注意点

  • 禁止在子类中重复定义父类已有的字段,避免字段隐藏导致的逻辑错误
  • 使用Lombok注解时,注意@AllArgsConstructor默认仅处理当前类的字段,父类字段需要手动通过构造函数或@SuperBuilder注解来赋值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 11:00:13