子类继承泛型父类后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
相关产品推荐
相关产品推荐

