Lombok 的@EqualsAndHashCode 注解:你真的了解它的重要性吗?

深入理解Java中的@EqualsAndHashCode注解 阅读详情

我今天在写代码时遇到了一个问题:IDEA提示我需要在类上添加@EqualsAndHashCode(callSuper = true)注解。这个类继承了一个父类,而这个注解似乎和父类有某种关联。之前我只用过@EqualsAndHashCode,从未遇到过需要设置callSuper = true的情况。这让我有些困惑,为什么需要添加这个参数?它的作用到底是什么呢?如果不加的话会有什么问题?

为什么需要 callSuper = true?

在 Java 开发中,确保对象比较和哈希计算逻辑正确是十分关键的。特别是在使用继承关系时,如何让子类正确地继承父类的行为可能并不直观。

Lombok 提供的 @EqualsAndHashCode 注解用于自动生成 equals() 和 hashCode() 方法。默认情况下,这些方法只会基于当前类中的字段进行生成,而忽略父类的字段。那么,问题来了:如果父类中有一些关键字段,它们是否应该参与对象比较和哈希计算?

如果父类的字段对对象的相等性有影响,那么需要使用 @EqualsAndHashCode(callSuper = true),以确保在生成的 equals() 和 hashCode() 方法中同时调用父类的 equals() 和 hashCode() 方法,继而比较父类的字段。

  • callSuper = false(默认):只比较子类的字段,不调用父类的 equals() 和 hashCode() 方法。
  • callSuper = true:同时调用父类的 equals() 和 hashCode() 方法,确保继承的父类字段也被比较。

来看一个例子,演示 callSuper = false 时的问题。假设我们有一个父类 SuperClass,它有一个 id 字段用于标识对象,而子类 SubClass 有一个 field 字段。我们希望在对象比较时,子类的 field 和父类的 id 都应该参与比较。

但如果我们使用 callSuper = false,则比较逻辑只会基于子类的字段,父类的字段会被忽略。这就可能导致两个对象虽然 field 相同,但 id 不同的情况下,被错误地认为是相等的。

@Getter
@Setter
@EqualsAndHashCode(callSuper = false)
public class SubClass extends SuperClass {
    private String field;
}

@Getter
@Setter
public class SuperClass {
    private int id;
}

在上面的代码中,callSuper = false 意味着 SubClass 的 equals() 和 hashCode() 方法只会基于 field 字段进行比较,完全忽略了 SuperClass 的 id 字段。

public static void main(String[] args) {
    SuperClass obj1 = new SubClass();
    obj1.setId(1);
    ((SubClass) obj1).setField("test");

    SuperClass obj2 = new SubClass();
    obj2.setId(2);
    ((SubClass) obj2).setField("test");

    System.out.println(obj1.equals(obj2));  // 输出 true,尽管 id 不同
}

在这个例子中,尽管 obj1 和 obj2 的 id 字段不同,但由于 callSuper = false,只比较了子类 field 字段,导致两个对象被错误地认为相等。

什么时候需要 callSuper = true?

如果父类的字段对相等性判断有影响,那么就需要将这些字段纳入到比较中,这时就应该使用 @EqualsAndHashCode(callSuper = true)。尤其是在继承复杂对象时,父类中的状态信息很可能是相等性判断的一部分。

通常在子类中,如果父类的状态(字段)对相等性和哈希计算有影响,省略 callSuper = true 可能会导致比较不完整,潜在引发问题。比如,在 HashSet 或 HashMap 这类集合中,hashCode() 和 equals() 的正确性直接影响到对象的存储、查找和删除操作。忽略父类的字段,可能导致数据处理错误。

不使用 callSuper = true 的后果是什么?

如果不加 @EqualsAndHashCode(callSuper = true),在继承父类的情况下,可能会在某些场景下引发问题,尤其是当父类的字段对对象的相等性和哈希值有重要影响时。

可能出现的问题:

忽略父类字段的比较,可能会引发一些隐藏的问题。例如,在使用 HashSet 或 HashMap 时,equals() 和 hashCode() 的行为不正确会导致数据无法正确插入、查找或删除。这类问题在集合操作中尤为常见,也会导致对象的唯一性判断失误。如:

  • HashSet 和 HashMap:这些基于 hashCode() 和 equals() 的集合操作会依赖这两个方法来判断对象的唯一性。如果 hashCode() 或 equals() 实现不完整,会导致对象插入、查找或删除操作异常。
  • TreeSet 或 TreeMap:这些集合在排序时也依赖比较方法,比较不完整会导致排序和逻辑错误。

数据丢失问题

如果子类实例序列化或反序列化时需要基于 equals() 和 hashCode() 做一致性检查,而这些方法没有考虑父类的字段,可能会导致数据处理的错误。

跨层级比较问题

如果在一个框架或模块中,某些比较逻辑要求完整考虑继承层次结构的所有字段,而你没有正确实现 equals() 和 hashCode(),可能会引发不可预期的行为。例如,在一些 ORM 框架或 Java Bean 比较时,这种问题会更容易暴露。

什么时候可以不用 callSuper = true?

当然,并不是所有情况都需要使用 callSuper = true。如果父类是一个无状态类,或者其字段不会影响对象比较,那么你可以选择不加这个注解。举个例子:

public class BaseEntity {
    private Long id;
}

@EqualsAndHashCode
public class Product extends BaseEntity {
    private String productName;
    private Double price;
}

在这个例子中,BaseEntity 的 id 字段可能只是数据库主键,用于标识而非用于比较。Product 类的相等性可能只取决于 productName 和 price,因此不需要加 callSuper = true。

此外,如果在比较或哈希计算时,父类的字段对结果没有任何影响,或这些字段的相等性不需要参与比较,那么也不需要加这个注解。例如,一些标识类或者仅用于子类行为扩展的父类,它们的字段不会影响子类对象的相等性判断。


在 IDEA 中,如果 Lombok 检测到你只覆盖了子类的 equals() 和 hashCode(),但没有包含父类字段,它会提醒你添加 callSuper = true 以确保完整性,但是不一定都要加上。

lombok的 @EqualsAndHashCode(callSuper = true) 在Java编程中,lombok是一个广泛使用的库,旨在通过注解自动生成样板代码,如 getters, setters, equals, hashCode 等,从而简化Java对象的创建。是 Lombok 提供的一个注解,用于自动地为类生成equals()方法和hashCode()方法。 阅读详情

相关推荐

Generating equals/hashCode implementation but without a call to superclass

文章目录Generating equals/hashCode implementation but without a call to superclass1、lombok 警告,没有注入父类的字段2、解决方式一:直接在子类上声明 @EqualsAndHashCode(callSuper = true)3、解决方式二[推荐]:在项目的src/main/java根目录下创建lombok配置文件1、c...

简简单单Onlinezuozuo 2万+

@EqualsAndHashCode(callSuper = true/false) 作用

首先 @EqualsAndHashCode 标在子类上 1. callSuper = true,根据子类自身的字段值和从父类继承的字段值来生成hashcode,当两个子类对象比较时,只有子类对象的本身的字段值和继承父类的字段值都相同,equals方法的返回值是true。 2.callSuper = false,根据子类自身的字段值 来生成hashcode,当两个子类对象比较时,只有子类对象的本身的字段值相同,父类字段值可以不同,equals方法的返回值是true。 package com.jt...

dj1955的博客 4万+

PowerBuilder 9.0安装组件全解析:Adaptive Server Anywhere、PowerDynamo、InfoMaker到底怎么选?

本文从技术架构师视角详细解析PowerBuilder 9.0安装组件选型策略,包括Adaptive Server Anywhere、PowerDynamo和InfoMaker的核心功能与应用场景。通过分析组件间的依赖关系和安装冲突机制,提供针对不同开发需求的最佳安装方案,帮助开发者高效配置PB9.0开发环境。

weixin_28700593的博客 443

@EqualsAndHashCode(callSuper = true)注解讲解

在上述代码中,DataScope类继承自HashMap,并且使用了@EqualsAndHashCode(callSuper = true)注解,表示要自动生成equals和hashCode方法,并且调用父类的equals和hashCode方法。在这段代码中,@EqualsAndHashCode(callSuper = true)注解表示要自动生成equals和hashCode方法,并且在生成的代码中调用父类(HashMap)的equals和hashCode方法。

还在活水泥的未来包工头 7650

组合导航、惯导、GNSS、INS、IMU的区别

‌:惯性导航系统(INS)是一种利用安装在运载体上的陀螺仪和加速度计来测定运载体位置的系统。它通过测量物体的加速度和角速度,结合算法计算出物体的位置、速度和姿态‌12。‌。

wynn1123的博客 8068

Flutter版本升级踩坑实录:从3.27到3.35,我们是如何修复Impeller引擎导致的花屏问题的?

本文详细记录了团队在Flutter版本升级过程中遇到的Impeller引擎导致的花屏问题及解决方案。从问题诊断到最终升级至稳定版3.35,文章分享了排查步骤、升级策略和性能对比数据,为开发者提供了实用的参考经验。

weixin_26854555的博客 511

Lombok 的 @EqualsAndHashCode(callSuper = false) 的使用

这个注解的作用就是自动的给model bean实现equals方法和hashcode方法。 但是,这个参数,callsuper = false 有问题吗? 你在使用这个注解的时候,确定知道“为什么要重写hashcode和equals方法吗?” 先看下面的测试。 两个model的代码我就截图啦:父类 TV.java 和 子类 小米TV.java,使用这个注解@EqualsAndHashCod...

请叫我大师兄 11万+

软考软件评测师备考避坑指南:过来人告诉你这5个章节最容易丢分(附2024最新考纲解析)

本文为软考软件评测师考生提供备考避坑指南,深度解析5个高频失分章节,包括标准化与信息化基础、中间件技术、软件测试模型、白盒测试覆盖准则和性能测试指标。文章结合2024最新考纲,分享实战技巧和记忆口诀,帮助考生精准打击失分重灾区,提升备考效率。

weixin_29223603的博客 468

Lombok 中 @EqualsAndHashCode注解的使用

@EqualsAndHashCode注解的作用就是自动实现model类的equals方法和hashcode方法。 我们在实际工作中经常会使用lombok来简化我们的开发,例如我们可以在定义的model类上添加@Data注解,从而免去手写get、set、toString、equals、hashcode等方法。 先来看问题: 1、定义一个基础类Car /** * 汽车 */ @Data public class Car { /** * 颜色 */ privat

Rookie_cc的博客 1万+

【从零开始玩量化7】easyTrader: 自动化(程序化)交易利器

前面的文章,我们介绍了数据获取工具AKShare, 量化回测工具backtrader等,这一篇,介绍程序化交易工具easyTrader。作者网名食灯鬼,目前项目在Github上的star数已经有6.7k。这可能是目前,开源能找到的,最好用的程序化交易库了。本文介绍了easyTrader的简单用法,这个包还有很多功能,后续再继续写文章探究。

量化投资助手的博客 1万+

eDP接口信号组成认识

eDP接口信号主要由Main Link、AUXCH与HPD三部分组成,如下图所示。 Main Link:表示主通道,用来传输各类型视频数据和音频数据; AUX CH:表示辅助通道,用于传输低带宽需求的数据,以及链路管理和设备控制信号; HPD:表示热插拔检测通道。 Main Link南1~4对数据线组成,每对数据线都是一对差分线。对于一款液晶屏而言,Main Link具体需几对数据线,这取决于屏幕的分辨率和彩色位数。 在该通道中传送的信号有视频像素信号、视频定时信号、视频格式信号、比特/像素及

精诚所至 2万+

Lombok常用注解使用方式和Lombok的@EqualsAndHashCode(callSuper = false)存在的问题

在认识 @EqualsAndHashCode 这个注解之前 , 我么首先需要知道 Lombok , 一 : Lombok 简介 Lombok项目是一个Java库,它会自动插入编辑器和构建工具中,Lombok提供了一组有用的注释,用来消除Java类中的大量样板代码。仅五个字符(@Data)就可以替换数百行代码从而产生干净,简洁且易于维护的Java类。 Lombok 常用注解: @Setter :注解在类或字段,注解在类时为所有字段生成setter方法,注解在字段上时只为该字段生成sette...

黄嚯嚯 4556

【UML】第12篇 序列图(1/2)——基本概念和构成

序列图(Sequence Diagram)是一种用于显示对象之间交互的图形化表示。它描述了在特定场景下,对象之间按照时间顺序进行的消息传递和协作过程。在序列图中,对象被表示为带有垂直虚线的矩形,虚线表示对象的生命周期。对象之间的交互通过箭头表示的消息来表示,箭头从一个对象的生命线指向另一个对象的生命线,表示消息的发送和接收。

AI人人懂 3051

Lombok 简介及 @EqualsAndHashCode 注解的影响

 Lombok简介 Lombok 是一种 Java™ 实用工具,可用来帮助开发人员消除 Java 的冗长,尤其是对于简单的 Java 对象(POJO)。它通过注解实现这一目的。 拿lombok官网的一个例子来说: public class Mountain{ private String name; private double longitude; priva...

_夜渐凉 978

AI测试实战:手把手教你做LLM(大模型)性能测试「含完整代码」

大模型API性能测试是评估模型服务响应能力、吞吐量和资源效率的关键手段。核心指标包括总响应时间、吐字率、首token延迟、输入/输出tokens数量、QPM等。测试流程涵盖构造负载、并发请求、数据采集和指标计算。优化建议针对吐字率低、首token延迟高、QPM偏低等问题,从模型、硬件、系统等多层面提出解决方案。

blues_C的博客 1431

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

lombok——@EqualsAndHashCode(callSuper = true)注解的使用

@EqualsAndHashCode(callSuper = true) 该注解用于子类对象之间进行比较的时候 不加该注解的影响:子类对象属性值一致,但其继承的父类对象属性值不一致,在比较的时候会出现比较结果不对的情况。 举个简单的例子: 这边先定义一个分类对象 Parent,有一个属性:code @Data public class Parent { /** * 父类编码 */ private String code; } 再定义一个子类对象 Child,一一个属性

weixin_44536553的博客 1万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Lombok---@EqualsAndHashCode(callSuper = true)的使用

package com.xiaobu.entity; import lombok.Data; import java.io.Serializable; /** * @author xiaobu * @version JDK1.8.0_171 * @date on 2020/9/1 9:24 * @description */ @Data public class Father implements Serializable { private static final long

小布1994的博客 1万+

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Lombok 的 @EqualsAndHashCode 在继承中的妙用 - 快马 AI 一键生成正确代码

Lombok 的是一个强大的工具,能够简化继承场景下的对象比较和哈希计算。通过这个注解,我们可以避免手动编写繁琐的代码,同时确保逻辑的正确性。结合InsCode(快马)平台的 AI 代码生成功能,开发者可以更高效地完成这类任务,专注于业务逻辑的实现。如果你还没有尝试过用快马生成代码,不妨现在就去体验一下,感受 AI 辅助开发的便捷!

EmeraldWolf23的博客 605

lombok的几个核心注解是什么?

Lombok核心注解总结(150字): Lombok通过注解简化Java开发,主要包含: 字段方法简化:@Data聚合Getter/Setter/ToString等;@Getter/@Setter单独控制访问权限 构造器生成:@NoArgsConstructor/@AllArgsConstructor/@RequiredArgsConstructor满足不同初始化需求 日志简化:@Slf4j自动生成Logger变量 对象构建:@Builder实现链式创建,@Value创建不可变类 实用工具:@NonNull

qq_45089709的博客 814

springboot注解-@EqualsAndHashCode

1、@EqualsAndHashCode(callSuper=false) 如果没有继承,仅对一个类加上@Data,不会有告警提示设置@EqualsAndHashCode(callSuper=false); 但存在继承,会有告警 @Data public class User extends Base{ private String userName; private St...

瞅你咋滴。 510

Lombok注解

Lombok插件@Accessors(chain = true)链式开发 加上@Accessors(chain = true) Person person = new Person(); person.setName("wang").setSex("男").setEmail("123@qq.com").setDate(new Date()).setAddr("山东"); Person person1 = new Person().setName("wang").setSex("男").setEmai...

yz18931904的博客 497

lombok-@EqualsAndHashCode(callSuper = true)注解的使用

该注解用于有继承关系的子类对象之间进行比较的时候: 不加该注解的影响:子类对象属性值一致,但其继承的父类对象属性值不一致,在比较的时候会出现比较结果不对的情况。 这是因为在@Data生成的 equals 方法,只对该类里自有的属性进行了比较 下面看下加与不加注解的时候编译后的子类 equals 方法 (1)无 @EqualsAndHashCode(callSuper = true) 注解 public boolean equals(Object o){ if (o == this) {

qq_44006819的博客 877

@EqualsAndHashCode

一定要加:数据库实体类必须正确实现equals()和hashCode()推荐配置:使用并只包含主键作用:确保集合操作、缓存、比较等场景的正确性性能:只比较主键,效率更高一致性:符合数据库记录比较的语义在你的 MyBatis-Plus 实体类中,建议都采用这种模式。这是企业开发中的最佳实践。

2301_80072306的博客 163

2024年最新你真的会用Lombok工具了吗?_lombok no constructor(2),Flutter最新开源框架

name的@Setter注解访问级别为protected和访问控制符一样,(img-oByXSTRi-1715878814172)](img-VFiY8fRB-1715878814172)]* 同包不同类就不能进行设置了,只能是同包同类可以访问setter方法。* password的@Setter注解访问级别为私有时,* 同包同类、同包不同类可以访问,不同包不同类就不能访问。

2401_84931310的博客 390
上一篇: Java里你为什么不用这种优雅的方式封装处理和抛出异常?
下一篇: 优秀持久层框架——MyBatis!
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值