5

Today is my first time to try Java language. When I try this code, I feel very strange:

int a =500;
System.out.println(System.identityHashCode(500));
System.out.println(System.identityHashCode(500));
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(a));

All of these results is different. But when I changed 500 to 50, It become the same result.

Why is it?

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
LeoShi
  • 1,637
  • 2
  • 14
  • 24
  • @Tichodroma How is this a duplicate? There is no String involved nor an Integer... But maybe I don't understand this thing well enough, because I am confused by the result of the code. (And I can confirm it) – brimborium Aug 09 '12 at 11:24
  • @brimborium Did you read the accepted answer to the question? Look for `500`. –  Aug 09 '12 at 11:25
  • @Tichodroma Yes. I get that this is closely linked... But I think this question is very well stated and is still **not** a duplicate. – brimborium Aug 09 '12 at 11:29

2 Answers2

12

But when I changed 500 to 50, It become the same result.

Autoboxing caches the conversion of primitives to Object. Small values get the same object, larger values do not.

Note: while values between -128 and 127 are always cached, Higher values can be cached depending on command line settings. See the source for Integer for more details.

This is also called a Flyweight Pattern


You can set the maximum size of the Integer cache with

-Djava.lang.Integer.IntegerCache.high=NNNN
-XX:AutoBoxCacheMax=NNNN
-XX:+AggressiveOpts  // sets it higher depending on the version e.g. 10000

http://martykopka.blogspot.co.uk/2010/07/all-about-java-integer-cache.html

http://www.javaspecialists.eu/archive/Issue191.html

I feel very strange

I know what you mean reading this question. ;)

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I didn't know about the command line setting; can you elaborate? I'm only seeing the `private static class IntegerCache` used by `Integer.valueOf(int i)`, which is what reminded me of _memoization_. – trashgod Aug 09 '12 at 11:54
  • 1
    @trashgod There is at least three options which alter the upper limit of the Integer cache. Added examples and links. – Peter Lawrey Aug 09 '12 at 12:09
  • @trashgod The Flyweight Pattern and Memorisation have similarities. Both try to reduce work by using a cache. – Peter Lawrey Aug 09 '12 at 12:11
  • Ok, I see it now: `IntegerCache` is the data structure and `valueOf()` is the static factory that recycles cached instances. +1 from earlier, BTW. – trashgod Aug 09 '12 at 17:30
  • It doesn't recycle the objects as such because they never go back. It just hands them out. It can do this because they are immutable. – Peter Lawrey Aug 09 '12 at 17:40
4

It caches the int value -128 and 127 (inclusive), So it will refer to same instance in memory within that range

When you pass primitive value to (here 10)

System.identityHashCode(10);

It autoboxes it to Integer object and it inturns uses valueOf() method of Integer class for conversion

For Example

Integer a = 10;

will get converted in to internally it uses valueOf()

1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

Integer.valueOf() which has got the cache implementation

public static Integer valueOf(int i) {
    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];
    else
        return new Integer(i);
}

so if you pass the value from -128 to 127(inclusive) it will use the cached version as you can see from

    if(i >= -128 && i <= IntegerCache.high)
        return IntegerCache.cache[i + 128];

See Also

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
  • 1
    +1 See also [_memoization_](http://en.wikipedia.org/wiki/Memoization). – trashgod Aug 09 '12 at 11:22
  • 1
    @trashgod I would call it a Flyweight Pattern as objects are cached to reduce object creation overhead, rather than results memorized to reduce calculation times. – Peter Lawrey Aug 09 '12 at 11:25