JPA实体类中toString、equals、hashCode的注解与实现方式疑问
@Entity @Getter @Setter @ToString(callSuper = true) @NoArgsConstructor public class Employee extends BaseEntity { // properties @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object other) { return super.equals(other); } }
问题1:重写方法直接调用父类、加@ToString(callSuper = true)是否合理、是否冗余
分两种情况判断:
- 手动重写的
hashCode()和equals()完全冗余:如果子类没有新增参与相等判断的属性,不需要主动重写这两个方法,直接继承父类实现即可,重写后调用父类的写法和不重写的效果完全一致,属于无效代码。 @ToString(callSuper = true)不属于冗余:Lombok的@ToString默认不会输出父类属性,加了callSuper = true配置后,才会把BaseEntity中的字段(比如常见的主键id、创建时间等公共字段)和Employee子类的字段一起打印,如果你需要在toString中看到父类属性,这个配置是必须的,除非你手动重写toString主动拼接父类属性。
注意:如果BaseEntity的equals/hashCode是基于主键实现,子类没有额外业务字段需要参与相等判断,完全可以删掉当前手动重写的两个方法。
问题2:注解实现是否比手动重写3-4行代码更优
绝大多数业务场景下注解实现更优:
- 代码更简洁,避免手写时的低级错误,比如equals方法类型判断错误、hashCode计算漏加字段等。
- 后续新增字段时不需要手动修改三个方法的实现,注解会自动同步新增字段,维护成本更低。
只有特殊场景适合手动重写:比如需要自定义相等判断规则(比如只判断业务唯一键不判断id、敏感字段不加入toString输出),这种时候手动实现的灵活度更高。
问题3:是否必须统一使用全注解或全手动重写的实现方式
这个认知有合理性,但不是强制要求,优先匹配实际需求:
- 从代码规范和可读性的角度来看,统一实现方式确实更好,其他维护者不需要额外猜测为什么部分方法用注解、部分方法手动写。
- 特殊场景可以例外,比如equals/hashCode直接复用父类实现不需要额外生成,toString需要自动生成包含父类字段的实现,这种情况只要补充注释说明原因即可,不需要为了强行统一写冗余代码。
当前的实现确实属于不规范的写法:要么删掉手动重写的equals和hashCode,只保留@ToString(callSuper = true);要么统一用Lombok注解,加上@EqualsAndHashCode(callSuper = true),效果和现在手动重写调用父类完全一致,代码更简洁。
内容的提问来源于stack exchange,提问作者user16979464
相关产品推荐
相关产品推荐

