整数等于 vs. = =

在 Java 1.5中,在很多情况下,您都可以将 Integerint交换。

然而,我在代码中发现了一个潜在的缺陷,这让我有点吃惊。

以下代码:

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

看起来是不正确的设置不匹配的时候,值是相等的,虽然我不能确定在什么情况下。我在 Eclipse 中设置了一个断点,发现 Integer值都是137,我检查了布尔表达式,它说它是 false,但是当我越过它时,它将错配设置为 true。

将条件语句更改为:

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

解决了问题。

有人能解释一下为什么会这样吗?到目前为止,我只在我自己的 PC 上看到了本地主机上的行为。在这个特殊的例子中,代码成功地通过了大约20次比较,但是在2次比较中失败了。这个问题一直是可重复的。

如果它是一个普遍的问题,那么它应该会在我们的其他环境(dev 和 test)中导致错误,但是到目前为止,在执行了数百个代码片段的测试之后,还没有人报告这个问题。

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

除了下面的所有答案之外,下面的 stackoverflow 链接还有相当多的附加信息。它实际上已经回答了我最初的问题,但因为我没有提到自动装箱在我的问题,它没有显示在选定的建议:

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

208838 次浏览

问题是您的两个 Integer 对象仅仅是,对象。它们不匹配,因为您比较的是两个对象引用,而不是其中的值。显然,重写 .equals是为了提供值比较,而不是对象引用比较。

Integer指的是引用,也就是说,当比较引用时,如果它们指向同一个对象,就要比较它们,而不是指向值。因此,你看到的问题。它之所以能够很好地处理简单的 int类型,是因为它解除了 Integer包含的值的盒子。

我可以补充一下,如果你正在做你正在做的事情,为什么要以 if语句开始呢?

mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );

JVM 缓存的是 Integer 值,因此与 ==的比较只适用于 -128和127之间的数字。

参考: # Immutable _ Objects _.2 F _ Wrapper _ Class _ Cache

你不能将两个 Integer和一个简单的 ==进行比较,因为它们是对象,所以大多数时间引用不会是相同的。

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

如果被装箱的值 p 为 true、 false、一个字节、 u0000到 u007f 范围内的一个字符,或者 -128到127之间的一个 int 或短数,那么设 r1和 r2是 p 的任意两个装箱转换的结果。R1 = = r2总是这种情况。


资源:

同样的话题:

“ = =”始终比较值的内存位置或对象引用。方法总是比较这些值。但是 equals 也间接地使用“ = =”运算符来比较值。

Integer 使用 Integer 缓存来存储从 -128到 + 127的值。如果 = = 运算符用于检查 -128到127之间的任何值,那么它将返回 true。除了这些值之外,它返回 false。

参考 链接获得更多信息

除了这些答案之外,我还了解到:

永远不要将对象与 = = 进行比较,除非你想要比较它们 通过他们的推荐信。

至于使用 ==的正确性,在进行 ==比较之前,你只需要拆箱一个比较过的 Integer值,比如:

if ( firstInteger.intValue() == secondInteger ) {..

第二个是自动拆箱(当然你必须首先检查 null)。