63

Possible Duplicate:
Weird Java Boxing

Recently I saw a presentation where was the following sample of Java code:

Integer a = 1000, b = 1000;  
System.out.println(a == b); // false  
Integer c = 100, d = 100;  
System.out.println(c == d); // true

Now I'm a little confused. I understand why in first case the result is "false" - it is because Integer is a reference type and the references of "a" and "b" is different.

But why in second case the result is "true"?

I've heard an opinion, that JVM caching objects for int values from -128 to 127 for some optimisation purposes. In this way, references of "c" and "d" is the same.

Can anybody give me more information about this behavior? I want to understand purposes of this optimization. In what cases performance is increased, etc. Reference to some research of this problem will be great.

Community
  • 1
  • 1
Beresta
  • 696
  • 1
  • 7
  • 9
  • 3
    You should note that you can not write code that depends on this behavior as other JVM/JDK implementors do not have to implement this optimization or if they want to, they can extend the range of the cached values. – Behrang Jun 28 '10 at 11:03
  • 5
    Note that caching does not apply to explicitly created objects. I.e. `Integer a = 1; Integer b = new Integer(1); System.out.println(a == b); // prints false` – ccpizza Dec 15 '15 at 21:25
  • @ccpizza It obviously doesn’t apply to explicitly created objects, since the JLS guarantees allocating and returning a new memory address after each new operator call. – Toni Nagy Mar 26 '21 at 20:11

2 Answers2

71

I want to understand purposes of this optimization. In what cases performance is increased, etc. Reference to some research of this problem will be great.

The purpose is mainly to save memory, which also leads to faster code due to better cache efficiency.

Basically, the Integer class keeps a cache of Integer instances in the range of -128 to 127, and all autoboxing, literals and uses of Integer.valueOf() will return instances from that cache for the range it covers.

This is based on the assumption that these small values occur much more often than other ints and therefore it makes sense to avoid the overhead of having different objects for every instance (an Integer object takes up something like 12 bytes).

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • 15
    Note that the cache only works if you use auto-boxing or the static method Integer.valueOf(). Calling the constructor will always result in a new instance of integer, even if the value of that instance is in the -128 to 127 range. – Tim Bender Jun 28 '10 at 10:52
  • Can anyone explain this phenomenon? http://ideone.com/DAI75m - why are two small values (< 128) that are different from each other declared as "not equal"? Since they are both cached, shouldn't they belong to the same Integer instance and hence "==" would return true since it is comparing their references? – David Doria Feb 08 '13 at 15:42
  • 2
    @David Doria: you seem to have serious misconceptions of what an "instance" is. It's fundamentally impossible to have two different values "belong to the same Integer instance". An Object instance is basically a region of memory. You can have multiple different instances with the same value, but not the other way round. The cache will return different instances for different values; it just ensures that you always get the same instance for the same value. – Michael Borgwardt Feb 08 '13 at 15:52
  • @MichaelBorgwardt could you reference a source of the caching information. Maybe JLS? – Olimpiu POP Aug 27 '14 at 09:33
  • @Michael: I still don't get it. If Integer uses 8 bytes to store numbers from -128 to +127, the user might at some point replace the small number with a number larger than 127. Then Integer would have to store it in a 16 bit space. So Integer would always have to keep an 8 bit space and a 16 bit space ready for storing a primitive int, right? So how does memory get saved. As I see it, they're using more memory. Or perhaps I missed something? – Nav Sep 17 '14 at 03:38
  • tried my best to explain the phenomena in simple words https://stackoverflow.com/a/64837154/6073148 – Zahid Khan Nov 14 '20 at 18:56
13

Look at the implementation of Integer.valueOf(int). It will return the same Integer object for inputs less than 256.

EDIT:

It's actually -128 to +127 by default as noted below.

Vladimir Vagaytsev
  • 2,871
  • 9
  • 33
  • 36
dty
  • 18,795
  • 6
  • 56
  • 82
  • 4
    Actually the default range is -128 <= i <= 127. There seems to be a System Property (java.lang.Integer.IntegerCache.high) that can influence the maximum value of an integer to get cached. – Andreas Jun 28 '10 at 09:13
  • 1
    Yep. Sorry, -128 to +127. Still, the point is, small values of i are cached! – dty Jun 28 '10 at 09:21
  • For more detailed answer, https://stackoverflow.com/a/64837154/6073148 – Zahid Khan Nov 14 '20 at 18:55