Monday, November 30, 2015

Internal representation of valueOf() in Java

                                        Internal representation of valueOf() in Java

public class ValueOf {

     public static void main(String[] args) {
           /*Integer i1 = 127;
           Integer i2 = 127; Equivalent to
           */
          Integer i1 = Integer.valueOf(127);
           Integer i2 = Integer.valueOf(127);
           System.out.println(i1 == i2);
           /*Integer i3 = 128;
           Integer i4 = 128; Equivalent to
           */
           Integer i3 = Integer.valueOf(128);
           Integer i4 = Integer.valueOf(128);

           System.out.println(i3 == i4);
     }
}
Output:

true
false

Integer.ValueOf() method creates the java.lang.Integer object by passing the specified ‘int‘ value. Actually, it doesn’t create the new objects for all the values you pass. This method is implemented such that the frequently used values are cached. I.e. internally it maintains an array of Integer objects where Integer objects for frequently requested values are created and stored at the time of VM initialization itself.

By default, these values will be from -128 to 127. So, for any number you pass between -128 and 127 (inclusive), it doesn’t create the new Integer object. Instead it returns already cached object from the array. If you pass the number beyond this range, then only it creates a new Integer object. Below is the source code ofInteger.valueOf() method.




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

From the above code, it is clear that Integer.valueOf() method doesn’t create new Integer objects for the values between IntegerCache.low and IntegerCache.high. Instead it returns the already cached object representing that value from IntegerCache.cache array. By default, IntegerCache.low = -128and  IntegerCache.high = 127. If you pass the values beyond this range, then only it creates new Integer object.
IntegerCache Class :

IntegerCache
 is the private static inner class of java.lang.Integer class. This is the class which handles the caching of all frequently requested values. Have a look at the source code of IntegerCache class.



private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}


You can notice that low is always set to -128 (Line 2). high gets the value from the property set in sun.misc.VM class (Line 10). That means you can change the upper limit of the range. 
If it is not set it gets the default value 127 (Line 21). cache is an Integer array where all the cached objects are stored. You observe from line 23 to line 26, it is where all Integer objects are created for the values from low to high and stored in cache array.

No comments:

Post a Comment