当前位置: 首页 > 面试题库 >

比较装箱的Long值127和128

郜振国
2023-03-14
问题内容

我想使用条件比较两个 Long 对象的值if。当这些值 小于128时if条件将正常工作,但是当这些 值大于或等于128时
,比较将失败。

例:

Long num1 = 127;
Long num2 = 127;

if (num1 == num2) {
    // Works ok
}

上面代码的比较正常进行,但是下面代码失败:

Long num1 = 128;
Long num2 = 128;

if (num1 == num2) {
    // Does NOT work
}

为什么将 Long 变量与 大于127的 值进行比较会出现问题?如果将变量数据类型更改为 长原语 ,则比较适用于所有情况。


问题答案:

TL; DR

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

长(双关语意)版本

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

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

  • 如果将值127cached )设置为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));                     // true
System.out.println(val3.longValue() == val4.longValue());  // true
System.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


 类似资料:
  • 问题内容: 我正在尝试按一个长对象对一个简单的对象列表进行排序- 下面的方法不起作用,因为长字符串之一被推到顶部只是因为它以较低的数字开头。所以我正在寻找一种方法可以直接根据实际的长值对它们进行排序 当前的obj实现如下所示。在该类中,我使用Collections.sort(trees); 问题答案: 为什么不实际在其中存放很长时间: 或先比较字符串的长度,然后再比较它们

  • 当有一个已定义的长值时,这种方法可以很好地工作。但是,当为null时,我不会得到结果。似乎运算符不能比较空值。 我尝试在子句中使用,但如果MAX结果为null,并且以下查询同时返回MAX Long值和null值,则只希望实体具有null值: 如何选择具有最大值的实体,或者如果没有设置,则获取为空的实体?

  • 问题内容: 输出: 输出: 注意:-128至127之间的数字为真。 问题答案: 当你使用Java编译数字文字并将其分配给Integer(大写)时,编译器将发出: 当你使用自动装箱时,也会生成此行代码。 valueOf 实现了“合并”某些数字,对于小于128的值,它将返回相同的实例。 从Java 1.6源代码的第621行: high可以使用system属性将的值配置为另一个值。 如果使用该系统属性运

  • 我读到这些方法返回值的规则是,对于obj1.compareTo(ob2),例如,如果ob2在层次结构中位于ob1之下,则返回值为负值,如果它位于ob1之上,则返回值为正(如果它等于,则返回值为0)。然而,在我的类中,我看到了使用Math.signum在compareTo方法中获得-1(表示负值)和1(表示正值)的示例。 有什么原因吗? 编辑: 以下是我的意思:

  • 我们知道,在数学中有很多用于比较大小的运算符。 在 JavaScript 中,它们的编写方式如下: 大于 / 小于:a > b,a < b。 大于等于 / 小于等于:a >= b,a <= b。 检查两个值的相等:a == b,请注意双等号 == 表示相等性检查,而单等号 a = b 表示赋值。 检查两个值不相等。不相等在数学中的符号是 ≠,但在 JavaScript 中写成 a != b。 在本