Java:整数等于 vs. ==

从Java 1.5开始,在许多情况下,您几乎可以与之互换。Integerint

但是,我在代码中发现了一个潜在的缺陷,这让我有点惊讶。

下面的代码:

Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
    mismatch = true;

当值相等时,似乎错误地设置了不匹配,尽管我无法确定在什么情况下。我在 Eclipse 中设置了一个断点,看到这些值都是 137,我检查了布尔表达式,它说它是假的,但是当我踩到它时,它把不匹配设置为 true。Integer

将条件更改为:

if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))

修复了问题。

谁能解释一下为什么会发生这种情况?到目前为止,我只在自己的PC上看到本地主机上的行为。在这种特殊情况下,代码成功地通过了大约 20 次比较,但在 2 次比较中失败了。该问题始终是可重现的。

如果这是一个普遍存在的问题,它应该在我们的其他环境(开发和测试)上导致错误,但到目前为止,在数百个测试执行此代码片段后,没有人报告该问题。

使用来比较两个值是否仍然不合法?==Integer

除了下面的所有详细答案之外,下面的stackoverflow链接还有相当多的附加信息。它实际上会回答我原来的问题,但是因为我在问题中没有提到自动装箱,所以它没有出现在选定的建议中:

为什么编译器/JVM不能让自动装箱“正常工作”?


答案 1

JVM 正在缓存整数值。因此,与 的比较仅适用于 -128 和 127 之间的数字。==

参考: #Immutable_Objects_.2F_包装_类_缓存


答案 2

你不能用一个简单的对象来比较两个,所以大多数时候引用是不一样的。Integer==

有一个技巧,在-128和127之间,引用将与缓存小整数的自动装箱使用相同。IntegerInteger.valueOf()

如果被装箱的值 p 是 true、false、一个字节、一个介于 \u0000 到 \u007f 范围内的 char,或者是一个介于 -128 和 127 之间的整数或短数字,则让 r1 和 r2 成为 p 的任意两个装箱转换的结果。总是 r1 == r2。


资源:

关于同一主题: