views:

142

answers:

4

So I was asked this question today.

Integer a = 3;
Integer b = 2;
Integer c = 5;
Integer d = a + b;
System.out.println(c == d);

What will this program print out? It returns true. I answered it will always print out false because of how I understood auto (and auto un) boxing. I was under the impression that assigning Integer a = 3 will create a new Integer(3) so that an == will evaluate the reference rather then the primitive value.

Can anyone explain this?

+9  A: 

Boxed values between -128 to 127 are cached. Boxing uses Integer.valueOf method, which uses the cache. Values outside the range are not cached and always created as a new instance. Since your values fall into the cached range, values are equal using == operator.

Quote from Java language specification:

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.

http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#5.1.7

Peter Štibraný
+1: you guys know so much :) Can you please provide a link to some documentation where we can learn more of this caching thing.
gameover
View the source of the JDK. Go to src.zip/java/lang/Integer.java and look for "cache = new Integer[256];". That's the initialization. Next, look for "public static Integer valueOf(int i)". That's one method that uses the cache to return the cached instante each time one of that values is asked for.
helios
java.lang.Character also has a caché for chars between unicodes 0 and 127 (ascii-7 / us-ascii).
helios
All the answers were great and comparably equal. Peter gets it for speed :)
John V.
Thanks. I've upvoted other equally good answers :)
Peter Štibraný
FindBugs is a good tool for analyzing code to get the benefit of this feature: http://findbugs.sourceforge.net/bugDescriptions.html#DM_NUMBER_CTOR
trashgod
Whether values outside the range create new instances or are cached is implementation dependent (although I believe most most if not all implementations act as you described).
ILMTitan
+9  A: 

This is what is really happening:

Integer c = Integer.valueOf(5);
Integer d = Integer.valueOf(a.intValue() + b.intValue());

Java maintains a cache of Integer objects between -128 and 127. Compare with the following:

Integer a = 300;
Integer b = 200;
Integer c = 500;
Integer d = a + b;
System.out.println(c == d);

Which should print false.

David Grant
+4  A: 

It's because some of the (auto-boxed) Integers are cached, so you're actually comparing the same reference -- this post has more detailed examples and an explanation.

netzwerg
+3  A: 

Caching happens outside of autoboxing too, consider this:

Integer a = 1;
Integer b = new Integer(1);
Integer c = Integer.valueOf(1);

System.out.println(a == b);
System.out.println(b == c);
System.out.println(c == a);

this will print:

false
false
true

So I guess that generally you want to stay away from '==' when comparing Objects

David Soroko
You're right. This is result of caching being implemented in `valueOf` method.
Peter Štibraný
Yes but amusingly not in Integer.valueOf(String s). What a mess.
David Soroko