Question

class Demo{
public static void main(String[] args) {  
     Integer i = Integer.valueOf(127);  
     Integer j = Integer.valueOf(127);        

     System.out.println(i==j);  

     Integer k = Integer.valueOf(128);  
     Integer l = Integer.valueOf(128);        

     System.out.println(k==l);  
  }  
}

The first print statement prints true whereas the second one prints false.Why? Please explain in detail.

Was it helpful?

Solution

It is because Integer caching.

From java language specification 5.1.7

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

Ideally, boxing a given primitive value p, would always yield an identical reference.

Integer i = Integer.valueOf(127);  
Integer j = Integer.valueOf(127);   

Both i and j point to same object. As the value is less than 127.

Integer k = Integer.valueOf(128);  
Integer l = Integer.valueOf(128);   

Both k & l point to different objects. As the value is greater than 127.
As, you are checking the object references using == operator, you are getting different results.


Update

You can use equals() method to get the same result

System.out.println(i.equals(j));//equals() compares the values of objects not references  
System.out.println(k.equals(l));//equals() compares the values of objects not references 

Output is

true
true  
  1. == operator checks the actual object references.
  2. equals() checks the values(contents) of objects.

Answer to comment

You have,

Integer i = Integer.valueOf(127); 

Here new object is created & reference is assigned to i

Integer j = Integer.valueOf(127); //will not create new object as it already exists 

Due to integer caching (number between -128 to 127) previously created object reference is assigned to j, then i and j point to same objects.

Now consider,

Integer p = Integer.valueOf(127); //create new object 
Integer q = Integer.valueOf(126); //this also creates new object as it does not exists  

Obviously both checks using == operator and equals() method will result false. As both are different references and have different vales.

OTHER TIPS

   i==j

is true for values between -128 and 127 due to integer caching.

From language spec

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

   Integer i = Integer.valueOf(127);   // new object
   Integer j = Integer.valueOf(127);   //cached object reference 
   Integer k = Integer.valueOf(128);   // new object
   Integer l = Integer.valueOf(128);   // new object

So i and j are pointing to same reference because of value 127.

Where as k and l pointing to difference references, because their value >127

There is a reason mentioned in docs for this behaviour:

The behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might

valueOf returns an Integer Object. Integer is a wrapper class for int. For your case,

Integer == Integer compares the actual object reference, where int == int will compare the values.

As already stated, values -128 to 127 are cached, so the same objects are returned for those.

If outside that range, separate objects will be created so the reference will be different.

You fix it by following way if you want same result for your both cases:

  • Make the types int
  • Cast the types to int or
  • Use .equals()
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top