Java: Integer equals vs. ==

狂风中的少年 提交于 2019-11-26 01:19:23

问题


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”?


回答1:


The JVM is caching Integer values. == only works for numbers between -128 and 127 http://www.owasp.org/index.php/Java_gotchas#Immutable_Objects_.2F_Wrapper_Class_Caching




回答2:


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 uses Integer.valueOf() which caches small integers.

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.


Resources :

  • JLS - Boxing

On the same topic :

  • autoboxing vs manual boxing java



回答3:


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.




回答4:


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 plain int types is that it unboxes the value contained by the Integer.

May I add that if you're doing what you're doing, why have the if statement to begin with?

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



回答5:


"==" 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



来源:https://stackoverflow.com/questions/3637936/java-integer-equals-vs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!