Java 比较两个Long类型对象是否相等

💥为什么要写这么一篇文章

今天同事遇到一个问题,测试那边进行反馈说两个用户出现不同的问题。后面经过排查发下。在比较用户ID是否与数据库中的一条数据的ID是否一致时遇到的问题。当用户ID是1L(Long类型非long),判断结果为true,而当另外一个用户ID是2912L时,判断结果却为false。为什么会出现这种问题呢?我当时只是觉得Long毕竟是个对象应该通过equals进行比较。后面为了深入了解,才发现不仅仅是那样。

问题如下

第一段代码

Long a=50L;
Long b=50L;
System.out.println(a==b);//a==b的结果true

第二段代码

Long c=128L;
Long d=128L;
System.out.println(c==d);//c==d的结果false

🎨两个执行比较,却是不相同的结果。产生这类的原因,查看源代码得知:

/**
 * Returns a {@code Long} instance representing the specified
 * {@code long} value.
 * If a new {@code Long} instance is not required, this method
 * should generally be used in preference to the constructor
 * {@link #Long(long)}, as this method is likely to yield
 * significantly better space and
 *  time performance by caching
 * frequently requested values.
 *
 * Note that unlike the {@linkplain Integer#valueOf(int)
 * corresponding method} in the {@code Integer} class, this method
 * is <em>not</em> required to cache values within a particular
 * range.
 *
 * @param  l a long value.
 * @return a {@code Long} instance representing {@code l}.
 * @since  1.5
 */
public static Long valueOf(long l) {
    final int offset = 128;
    if (l >= -128 && l <= 127) { // will cache
        return LongCache.cache[(int)l + offset];
    }
    return new Long(l);
}

🎨个人通过翻译工具稍微翻译了一下方法注释,如有不对之处,可以帮忙指出一下。

返回一个{@code Long}实例,表示指定的{@code Long}值。
如果不需要新的{@code Long}实例,则通常应该优先使用此方法而不是构造函数{@link #Long(Long)},因为该方法通过缓存频繁请求的值可能会产生更好的空间和时间性能。
注意,与{@code Integer}类中的{@linkplain Integer#valueOf(int)对应方法}不同,该方法<em>不是</em>需要缓存特定范围内的值。

✒️非常粗糙的翻译,但是大致也能知道这个方法是通过缓存特定范围内的值,以达到更好的空间和时间性能。从方法体中也可以看到LongCache缓存以及当Long的值在[-128,127]之间是不会new一个实例的。而当Long的值不在在[-128,127]之间内时候则会进行new出一个实例,这样就导致==比较时出现错误

解决方案

方案一

Long c = 128L;
Long d = 128L;
c.longValue() == d.longValue() //true

方案二(推荐)

Long c = 128L;
Long d = 128L;
c.equals(d);//true

Long中的equals源码

/**
* Compares this object to the specified object.  The result is
* {@code true} if and only if the argument is not
* {@code null} and is a {@code Long} object that
* contains the same {@code long} value as this object.
*
* @param   obj   the object to compare with.
* @return  {@code true} if the objects are the same;
*          {@code false} otherwise.
*/
public boolean equals(Object obj) {
   if (obj instanceof Long) {
       return value == ((Long)obj).longValue();
   }
   return false;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AloneMou

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值