前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >注意 Lombok equals 方法的陷阱

注意 Lombok equals 方法的陷阱

原创
作者头像
Lorin 洛林
发布2024-06-20 13:38:07
1100
发布2024-06-20 13:38:07
举报
文章被收录于专栏:Java 技术小屋Java 技术小屋

版本

  • JDK 8
  • Lombok 1.18.12

问题

  • 今天一位网友在群里问到,Lombok @Data equals 方法对比两个对象,两个对象的值不相等,但结果为 True,下面我们来看看具体的代码:
代码语言:Java
复制
package test;

import lombok.Data;
import lombok.EqualsAndHashCode;

@Data
@EqualsAndHashCode
class Vehicle {
    private int id;
    private String name;
}

@Data
class Bicycle extends Vehicle {
    private String run;
}

public class LombokTest {
    public static void main(String[] args) {
        Bicycle bicycle1 = new Bicycle();
        bicycle1.setId(1);
        bicycle1.setName("捷安特");
        bicycle1.setRun("run");

        Bicycle bicycle2 = new Bicycle();
        bicycle2.setId(1);
        bicycle2.setName("捷安特1");
        bicycle2.setRun("run");

        boolean equals = bicycle1.equals(bicycle2);
        System.out.println(equals);  // 打印 true
    }
}
  • 仔细看一下相信机智的朋友们就已经知道原因了,Lombok equals 方法默认不会调用父类的 equals 方法,而 name 字段属于父类字段,所以比较结果为 True
  • 我们看一下 Lombok 生成的 equals 方法:
代码语言:Java
复制
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Bicycle)) {
            return false;
        } else {
            Bicycle other = (Bicycle)o;
            if (!other.canEqual(this)) {
                return false;
            } else {
                // 仅比较子类字段的值
                Object this$run = this.getRun();
                Object other$run = other.getRun();
                if (this$run == null) {
                    if (other$run != null) {
                        return false;
                    }
                } else if (!this$run.equals(other$run)) {
                    return false;
                }

                return true;
            }
        }
    }
  • 如果我们需要同时比较父类字段和子类字段如何实现呢?其实很简单,添加注解 @EqualsAndHashCode(callSuper = true) 表示调用 equals & hashCode 方法时同时调用父类方法。
代码语言:Java
复制
@EqualsAndHashCode(callSuper = true)
@Data
class Bicycle extends Vehicle {
    private String run;
}

// 再次执行源代码结果为 False
  • 添加注解 @EqualsAndHashCode(callSuper = true) 生成的 equals 方法:
代码语言:Java
复制
    public boolean equals(final Object o) {
        if (o == this) {
            return true;
        } else if (!(o instanceof Bicycle)) {
            return false;
        } else {
            Bicycle other = (Bicycle)o;
            if (!other.canEqual(this)) {
                return false;
            // 调用父类 equals 方法
            } else if (!super.equals(o)) {
                return false;
            } else {
                Object this$run = this.getRun();
                Object other$run = other.getRun();
                if (this$run == null) {
                    if (other$run != null) {
                        return false;
                    }
                } else if (!this$run.equals(other$run)) {
                    return false;
                }

                return true;
            }
        }
    }

个人简介

👋 你好,我是 Lorin 洛林,一位 Java 后端技术开发者!座右铭:Technology has the power to make the world a better place.

🚀 我对技术的热情是我不断学习和分享的动力。我的博客是一个关于Java生态系统、后端开发和最新技术趋势的地方。

🧠 作为一个 Java 后端技术爱好者,我不仅热衷于探索语言的新特性和技术的深度,还热衷于分享我的见解和最佳实践。我相信知识的分享和社区合作可以帮助我们共同成长。

💡 在我的博客上,你将找到关于Java核心概念、JVM 底层技术、常用框架如Spring和Mybatis 、MySQL等数据库管理、RabbitMQ、Rocketmq等消息中间件、性能优化等内容的深入文章。我也将分享一些编程技巧和解决问题的方法,以帮助你更好地掌握Java编程。

🌐 我鼓励互动和建立社区,因此请留下你的问题、建议或主题请求,让我知道你感兴趣的内容。此外,我将分享最新的互联网和技术资讯,以确保你与技术世界的最新发展保持联系。我期待与你一起在技术之路上前进,一起探讨技术世界的无限可能性。

📖 保持关注我的博客,让我们共同追求技术卓越。

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 版本
  • 问题
  • 个人简介
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档