21

The output of current program is "Strange". But both the variables share the same reference. Why are the second and third comparisons not true?

Integer a; Integer b; a = new Integer(2); b = a; if(b == a) { System.out.println("Strange"); } a++; if(b == a) { System.out.println("Stranger"); } a--; if(b == a) { System.out.println("Strangest"); } 

Output: Strange

2
  • Unboxing is probably the answer. However, I have no real idea. Commented Jun 21, 2010 at 14:11
  • 13
    +1 for demonstrating an unforgivable use of autoboxing. Commented Jun 21, 2010 at 14:18

3 Answers 3

24

That's the artifact of autoboxing and a fact that Integer is immutable in Java.

The a++ and a-- are translated to roughly this.

int intA = a.getInt( ); intA++; a = Integer.valueOf( intA ); // this is a reference different from b 
Sign up to request clarification or add additional context in comments.

6 Comments

Note that if you replace a = new Integer(2) with a = Integer.valueOf(2), "Strangest" will also be printed since it will use the integer cache for getting the instance.
What do you mean by integer cache in your comment. can you elaborate ?
@restrictedinfinity. At least in Sun's Java, Byte, Short and Integer have a cache of 256 values ranging from -128 to 127 inclusive that are served by Type.valueOf( ) method. So in our case after a-- the int value is 2 and that would be the same that we have started with, so Integer.valueOf( 2 ) would have returned the same Integer object. Note, that Long type does not have a cache, therefore Long.valueOf always returns a new object.
@Alexander: It can be safely assumed that this behaviour holds true for all JVM implementations since it is a part of the specification.
@glowcoder: I was actually correcting the statement "At least in Sun's Java, Byte, Short and Integer have a cache of 256 values ranging from -128 to 127 inclusive that are served by Type.valueOf( ) method" since he didn't really need to mention "Sun" Java; this behaviour is consistent across all implementations since it's a part of the specification. Of course, as you correctly observed, nothing definitive can be said about values which don't fall in the range decided by the specification.
|
8
  • Strage - it's obvious, the two variables point to the same object

  • not Stranger because of autoboxing. Integer is immutable, so each operation on it creates a new instance.

  • not Strangest, because of the previous point, and because you have used new Integer(..) which ignores the cache that is used for the byte range. If you use Integer.valueOf(2) initially, then the cached Integers will be used and Strangest will also be printed.

Comments

0

An Integer object is immutable, any change in an existing object will create a new object. So after a++, a new object will be created and a will start pointing to that new object while b is still pointing to the old object. Hence, after a++, a and b are pointing to different objects and a == b will always return false.

with respect to the mentioned example :

Integer a; //created Integer reference Integer b; //created Integer reference a = new Integer(2);//created new Integer Object and a reference is assigned to that new object b = a;//b also start pointing to same Integer object if(b == a) { // b==a will be true as both are pointing to same object System.out.println("Strange"); } a++; //after a++ , a new Integer object will be created (due to Integer immutablity and a will point to that new object while b is still pointing to old), so b==a will be false if(b == a) { System.out.println("Stranger"); } a--; //again a new Integer Object will be created and now a will start pointing to that new Object , so b==a will be false if(b == a) { System.out.println("Strangest"); } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.