Java:整数等于与==
从 Java 1.5 开始,在许多情况下您几乎可以将 Integer
与 int
互换。
然而,我在代码中发现了一个潜在的缺陷,这让我有点惊讶。
以下代码:
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 次比较中失败了。该问题始终可以重现。
如果这是一个普遍的问题,它应该会在我们的其他环境(开发和测试)上导致错误,但到目前为止,在执行此代码片段的数百次测试后,没有人报告该问题。
使用 ==
比较两个 Integer
值仍然不合法吗?
除了下面的所有详细答案之外,下面的 stackoverflow 链接还有很多附加信息。它实际上会回答我原来的问题,但因为我在问题中没有提到自动装箱,所以它没有出现在选定的建议中:
As of Java 1.5, you can pretty much interchange Integer
with int
in many situations.
However, I found a potential defect in my code that surprised me a bit.
The following code:
Integer cdiCt = ...;
Integer cdsCt = ...;
...
if (cdiCt != null && cdsCt != null && cdiCt != cdsCt)
mismatch = true;
appeared to be incorrectly setting mismatch when the values were equal, although I can't determine under what circumstances. I set a breakpoint in Eclipse and saw that the Integer
values were both 137, and I inspected the boolean expression and it said it was false, but when I stepped over it, it was setting mismatch to true.
Changing the conditional to:
if (cdiCt != null && cdsCt != null && !cdiCt.equals(cdsCt))
fixed the problem.
Can anyone shed some light on why this happened? So far, I have only seen the behavior on my localhost on my own PC. In this particular case, the code successfully made it past about 20 comparisons, but failed on 2. The problem was consistently reproducible.
If it is a prevalent problem, it should be causing errors on our other environments (dev and test), but so far, no one has reported the problem after hundreds of tests executing this code snippet.
Is it still not legitimate to use ==
to compare two Integer
values?
In addition to all the fine answers below, the following stackoverflow link has quite a bit of additional information. It actually would have answered my original question, but because I didn't mention autoboxing in my question, it didn't show up in the selected suggestions:
Why can't the compiler/JVM just make autoboxing “just work”?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
JVM 正在缓存整数值。因此,与
==
的比较仅适用于 -128 和 127 之间的数字。请参阅:#Immutable_Objects_.2F_Wrapper_Class_Caching
The JVM is caching Integer values. Hence the comparison with
==
only works for numbers between -128 and 127.Refer: #Immutable_Objects_.2F_Wrapper_Class_Caching
您无法将两个
Integer
与简单的==
进行比较,它们是对象,因此大多数时候引用不会相同。有一个技巧,
Integer
介于 -128 和 127 之间,引用将与自动装箱使用Integer.valueOf()
缓存小整数相同。资源:
同一主题:
You can't compare two
Integer
with a simple==
they're objects so most of the time references won't be the same.There is a trick, with
Integer
between -128 and 127, references will be the same as autoboxing usesInteger.valueOf()
which caches small integers.Resources :
On the same topic :
“==”始终比较值的内存位置或对象引用。 equals 方法总是比较值。但 equals 也间接使用“==”运算符来比较值。
Integer 使用 Integer 缓存来存储从 -128 到 +127 的值。如果 == 运算符用于检查 -128 到 127 之间的任何值,则返回 true。对于除这些值之外的其他值,它返回 false 。
请参阅链接了解一些其他信息
"==" always compare the memory location or object references of the values. equals method always compare the values. But equals also indirectly uses the "==" operator to compare the values.
Integer uses Integer cache to store the values from -128 to +127. If == operator is used to check for any values between -128 to 127 then it returns true. for other than these values it returns false .
Refer the link for some additional info
Integer
指的是引用,也就是说,在比较引用时,您要比较的是它们是否指向同一对象,而不是值。因此,出现了您所看到的问题。它能够很好地处理普通int
类型的原因是它对Integer
包含的值进行拆箱。我可以补充一点,如果您正在做您正在做的事情,为什么要以
if
语句开头呢?Integer
refers to the reference, that is, when comparing references you're comparing if they point to the same object, not value. Hence, the issue you're seeing. The reason it works so well with plainint
types is that it unboxes the value contained by theInteger
.May I add that if you're doing what you're doing, why have the
if
statement to begin with?问题是你的两个 Integer 对象就是那个对象。它们不匹配,因为您正在比较两个对象引用,而不是其中的值。显然
.equals
被重写以提供值比较,而不是对象引用比较。The issue is that your two Integer objects are just that, objects. They do not match because you are comparing your two object references, not the values within. Obviously
.equals
is overridden to provide a value comparison as opposed to an object reference comparison.除了这些给出的很好的答案之外,我学到的是:
Besides these given great answers, What I have learned is that:
为了确保使用
==
的正确性,您可以在进行==
比较之前取消比较的Integer
值之一,例如:第二个将是自动拆箱(当然,您必须首先检查
null
)。As well for correctness of using
==
you can just unbox one of comparedInteger
values before doing==
comparison, like:The second will be auto unboxed (of course you have to check for
null
s first).