Java:Integer等于==

从Java 1.5开始,在很多情况下,你几乎可以用Integer来交换Integer

不过,我在代码中发现了一个潜在的缺陷,这让我感到很惊讶。

以下代码:

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

似乎是错误的设置不匹配时,值是相等的,虽然我不能确定在什么情况下。 我在Eclipse中设置了一个断点,看到Integer值都是137,我检查了布尔expression式,它说这是错误的,但是当我跨过它,它是设置不匹配为真。

将条件更改为:

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

解决了这个问题。

谁能说出为什么发生这种情况? 到目前为止,我只在自己的电脑上看到了本地主机上的行为。 在这个特定的情况下,代码成功地通过了大约20个比较,但在2失败。问题是始终可重现的。

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

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

除了下面的所有好的答案外,下面的计算器链接还有相当多的附加信息。 它实际上会回答我原来的问题,但因为我没有提到我的问题的自动装箱,它没有出现在选定的build议:

为什么编译器/ JVM不能使自动装箱“只是工作”?

JVM正在caching整数值。 ==只适用于-128到127之间的数字http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching

你不能比较两个Integer与一个简单的==它们是对象,所以大部分时间参考将不会是相同的。

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

如果p的值为真,false,一个字节,范围在\ u0000到\ u00f之间的一个字符,或者在-128到127之间的一个int或者一个短数字,那么让r1和r2是任意两个装箱转换的结果p。 r1 == r2总是如此。


资源:

  • JLS – 拳击

在同一主题上:

  • 自动装箱与手动拳击Java

问题是你的两个Integer对象就是那个对象。 它们不匹配,因为您正在比较两个对象引用,而不是内部的值。 显然.equals被重写提供了一个值比较而不是对象引用的比较。

Integer是指引用,也就是说,比较引用时,你是比较指向同一个对象,而不是值。 因此,你看到的问题。 使用纯inttypes的原因是它将Integer包含的值解开。

我可以补充一点,如果你正在做你在做什么,为什么有if语句开头呢?

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

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

整数使用整数caching来存储从-128到+127的值。 如果==运算符用于检查-128到127之间的任何值,则返回true。 除了这些值以外,它返回false。

请参阅链接了解更多信息