比较装箱的Long值127和128

比较装箱的Long值127和128,第1张

比较装箱的Long值127和128

TL; DR

Java将装箱的Integer实例从缓存

-128
127
。由于您
==
用于比较对象 引用 而不是
,因此只有缓存的对象会匹配。使用未
long
装箱的原始值或用于
.equals()
比较
Long
对象。

长(双关语意)版本

为什么将Long变量与大于127的值进行比较时会出现问题?如果上述变量的数据类型是原始(长整数),则代码对所有值有效。

Java缓存范围从-128到127的Integer对象实例
。说:

  • 如果将值
    127
    cached )设置为N个Long变量,则所有引用将指向同一对象实例。(N个变量,1个实例)
  • 如果将值
    128
    不缓存 )设置为N个Long变量,则每个引用都将指向一个对象实例。(N个变量,N个实例)

这就是为什么:

Long val1 = 127L;Long val2 = 127L;System.out.println(val1 == val2);Long val3 = 128L;Long val4 = 128L;System.out.println(val3 == val4);

输出此:


对于 127L 值,由于两个引用(val1和val2)都指向内存(已缓存)中的同一对象实例,因此它返回

true

另一方面,对于 128
值,由于在内存中没有高速缓存的实例,因此将为盒装值的所有新分配创建一个新实例,从而导致两个不同的实例(由val3和val4指向)并

false
在他们之间的比较。

发生这种情况的唯一原因是,您正在将两个

Long
对象引用
(而不是
long
原始值)与
==
运算符进行比较。如果不是这种缓存机制,那么这些比较将 始终
失败,因此,这里的真正问题是将装箱的值与
==
运算符进行比较。

将这些变量更改为基本

long
类型将防止这种情况的发生,但是如果您需要使用
Long
对象来保持代码,则可以使用以下方法安全地进行这些比较:

System.out.println(val3.equals(val4));          // trueSystem.out.println(val3.longValue() == val4.longValue());  // trueSystem.out.println((long)val3 == (long)val4);   // true

(即使对于铸造,也必须进行正确的空检查)

IMO ,在处理对象比较时始终使用 .equals() 方法始终是一个好主意。

参考链接:

  • https://today.java.net/pub/a/today/2005/03/24/autoboxing.html
  • https://blogs.oracle.com/darcy/entry/boxing_and_caches_integer_valueof
  • http://java.dzone.com/articles/surprising-results-autoboxing


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4924665.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存