前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Objects.equals很好,使用不当就会踩“坑”T_T

Objects.equals很好,使用不当就会踩“坑”T_T

作者头像
烟雨平生
发布2024-07-10 14:08:48
800
发布2024-07-10 14:08:48
举报
文章被收录于专栏:数字化之路

因为这个Bug,额外多花了0.5h排查问题。

需要节省时间的粉丝继续:

  1. 使用可读性更好的常量替代魔法数字
  2. 使用Objects.equals判断两个值相等

上面的招式都是CleanCode一书讲的标准套路,可是,居然也出了bug!!!

你说,找谁评理去!!!

哪位粉丝朋友看到是错在哪了?

所以之后的比较都改成了Objects.equals。之后惨案发生了

就是这个地方出问题了:

化繁为简,来换个写法,复现下这个Bug:

直接看结果:

源码见文末

为什么呢?

使用Objects.equals(Object a,Object b)方法判断两个值是否相等时,一定要保证两个入参的类型要一致。 否则即使两个值相同,但其结果仍然会返回false。

知其然,也要知其所以然。 上源码【Show the code】: java.util.Objects#equals

代码语言:javascript
复制
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

step1: a == b

Integer常量池中的1和Long常量池中的1不是同一个对象。 虽然它们的值相同,但它们属于不同类型的常量池,所以Integer类型1的对象地址 != Long类型1的对象地址。即a!=b

step2: a != null

此处a是1,不为null

step3: a.equals(b)

在本例中,a是Integer类型,所以java.lang.Integer#equals

代码语言:javascript
复制
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

b是Long类型,直接return false;

结论: (Objects.equals(1, 1L)).isFalse成立

除此之外,还有Long、Byte、Short、Double、Float、Boolean和Character也有类似的equals方法判断逻辑。

【碎碎念】 写业务代码时,常踩坑的场景: Long类型和Integer类型比较,比如:用户id的场景。 Byte类型和Integer类型比较,比如:状态判断的场景。 Double类型和Integer类型比较,比如:金额为0的判断场景。

源码

代码语言:javascript
复制
代码语言:javascript
复制
import org.junit.jupiter.api.Test;
import java.util.Objects;
import static org.assertj.core.api.Assertions.assertThat;

/**
 * @Auther: cheng.tang
 * @Date: 2024/7/5
 * @Description: tool-box
 */
public class ObjectsEqualsTest {

    @Test
    public void equalsTest() {
        assertThat(Objects.equals(1, 1L)).isFalse();
    }

}

这两天的上海也热起来了,昨天晚上没盖被子也热醒了二次

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 的数字化之路 微信公众号,前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • step1: a == b
  • step2: a != null
  • step3: a.equals(b)
  • 源码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档