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
是指引用,也就是说,比较引用时,你是比较指向同一个对象,而不是值。 因此,你看到的问题。 使用纯int
types的原因是它将Integer
包含的值解开。
我可以补充一点,如果你正在做你在做什么,为什么有if
语句开头呢?
mismatch = ( cdiCt != null && cdsCt != null && !cdiCt.equals( cdsCt ) );
“==”总是比较值的内存位置或对象引用。 equals方法总是比较值。 但是equals也间接使用“==”运算符来比较这些值。
整数使用整数caching来存储从-128到+127的值。 如果==运算符用于检查-128到127之间的任何值,则返回true。 除了这些值以外,它返回false。
请参阅链接了解更多信息