Boxed Primitives and Equivalence
Asked Answered
G

4

17

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?

Gladwin answered 7/1, 2010 at 15:29 Comment(3)
@CiroSantilli六四事件法轮功包卓轩 How is it possible mine is a duplicate of that one when mine was asked four years earlier. Let's at least consider order of events with duplicate posts.Gladwin
meta.stackexchange.com/questions/147643/…Sedimentary
But possible duplicate of #1700581 is more appropriate, the previous one was wrong. But maybe both are wrong ;-)Sedimentary
R
22

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://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

Reconstruction answered 7/1, 2010 at 15:33 Comment(7)
+1: you guys know so much :) Can you please provide a link to some documentation where we can learn more of this caching thing.Pituri
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.Polar
java.lang.Character also has a caché for chars between unicodes 0 and 127 (ascii-7 / us-ascii).Polar
All the answers were great and comparably equal. Peter gets it for speed :)Gladwin
FindBugs is a good tool for analyzing code to get the benefit of this feature: findbugs.sourceforge.net/bugDescriptions.html#DM_NUMBER_CTORVerify
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).Motherly
Caching -127 to 127 is not true anymoreChatterer
C
11

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.

Chace answered 7/1, 2010 at 15:34 Comment(0)
P
5

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.

Phelia answered 7/1, 2010 at 15:36 Comment(0)
B
5

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

Generally you want to stay away from == when comparing Objects

Beforehand answered 7/1, 2010 at 15:50 Comment(2)
You're right. This is result of caching being implemented in valueOf method.Memorabilia
Yes but amusingly not in Integer.valueOf(String s). What a mess.Beforehand

© 2022 - 2024 — McMap. All rights reserved.