My question is why (i1==i2)=false,(i3==i4)=false and (i5==i6)=true?

public class comp {
   public static void main(String[] args){
	   Integer i1 = 2001;
	   Integer i2 = 2001;
	   System.out.println((i1==i2) + " " + (i1.equals(i2)));
	   Integer i3 = 21;
	   Integer i4 = new Integer(21);
	   System.out.println((i3==i4) + " " + (i3.equals(i4)));
	   Integer i5 = 21;
	   Integer i6 = 21;
	   System.out.println((i5==i6) + " " + (i5.equals(i6)));
   }
}

The results are as below:

false true
false true
true true

Thank You.

I suspect that it is the age old problem of == and Object references.
The == with object references tests if the two variables refer to the same object.

Generate the byte code and look at it to see what the compiler is doing.

The Integers are different Objects, even if their values happen to be the same EXCEPT that Java pre-creates a single set of Integers for values -1287 to +127 (approx - or maybe its 0-255, but you get the idea) so Integers in this range will always be the same Object for the same value.

Therefore when comparing a wrapper object other than Boolean using the "==" symbol it's value has to be between 0 to 255. Otherwise it will throw a false value. Am I correct?.

It MAY be false. The compiler tries to re-use Objects where possible, so depending on the exact way it's coded two different Integers (with the same value) MAY be optimised to the same Object and therefore be ==. The moral is never to use == on any kind of Object unless you are certain that that's what you mean.

ps The default range of values for which Java uses a pre-cached Integer is -128 to +127, but you can use the java.lang.Integer.IntegerCache.high property to increase the size of this cache.

Edited 5 Years Ago by JamesCherrill: ps

Therefore when comparing a wrapper object other than Boolean using the "==" symbol it's value has to be between 0 to 255. Otherwise it will throw a false value. Am I correct?.

No, not really. This may be a rule of thumb that works some of the time, but it's not defined behavior so you're just relying on the way things happen to be right now. Could change with the next release, and then your code goes belly up and kicks weakly a few times before winging its way to the land where code is eternally blessed. Don't rely on stuff that happens to work, rely on the spec.

When comparing a wrapper object, always use .equals unless you actually mean to compare identity. The only reason to have a line like if (objectA == objectB) is if you want to know whether the two are identical, that is if you want to know whether objectA.setSomeVariable(someValue) will change the value of objectB.someVariable.


(there is one use for this sort of thing: if you're planning on entering some code in the thedailywtf.com's Disgruntled Employee competition, this would make a great delayed-action logic bomb)

This article has been dead for over six months. Start a new discussion instead.