比较两个整数:为什么“==”为真?

3

可能是重复问题:
包装类和==操作符

你好,当我使用 == 比较整数时出现了一些问题,所以你能解释一下为什么第二个测试也成功了吗?

@Test
public void integerTest() {
    Integer prvni = 127;
    Integer druhy = 127;
    Integer treti = 128;
    Integer ctvrty = 128;

    assertTrue(prvni == druhy);
    assertTrue(treti != ctvrty);

}

1
同时:https://dev59.com/nG435IYBdhLWcg3w9FBY - Sean Patrick Floyd
3个回答

11

使用==比较对象时,实际上是在比较引用。也就是说,两个断言都为真的原因是因为prvnidruhy 引用同一个对象,而tretictvrty则不是。

这是因为JVM在-128到127范围内缓存Integer对象,并在自动装箱值时重用缓存的对象。

除非您切换到int,否则可以通过prvni.intValue()或使用prvni.equals(...)来进行比较。


如果你将128更改为该范围内的数字(例如125),代码将按预期工作。为什么Java不会在运行时缓存数字呢? - leifg
范围不正确——应该是-128到127。 - Platinum Azure
1
Java使用数组作为Integer缓存的后备存储。数组无法在运行时调整大小,也不能用于稀疏结构(即,在没有缓存对象之间缓存远离的值)。可以使用Hashtable或类似的东西,但这些只允许具有Object键,这意味着您必须使用Integer对象(而不是int原语)作为键,这又引出了整个问题!因此,唯一的选择是使用具有合理范围的数组。 - Platinum Azure

1

自从Java 1.5以来,一些包装类引入了缓存。对于Integer,在-128到127之间的任何数字都会被缓存。其他值需要每次都包装成一个new Integer

==运算符比较的是引用。由于127的缓存Integer值实际上是同一个对象,所以==返回true。对于128个Integer对象,它们是两个不同的对象,没有相同的引用相等性。

有两种更可靠的方法可以进行相等比较:

if (treti.equals(ctvrty)) { /* do something */ }

或者:

if (treti.compareTo(ctvrty) == 0) { /* do something */ }

后面的比较利用了 Integer 实现了 Comparable 接口,因此定义了一个 compareTo 方法,如果第一个对象“小于”第二个对象,则返回负值,如果第一个对象“大于”第二个对象,则返回正值,如果对象相等,则返回零。

-2
自动装箱功能为每个对象创建一个新实例。
试试这个:
int treti = 128;
int ctvrty = 128;

-1:没有解释为什么 127 的情况有效,并且没有完全回答问题。请查看包装类缓存。 - Platinum Azure

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接