Java Wrapper Classes Internal Caching

All of us know how to create objects in java i.e. using new keyword. There are other ways to create instances of a class, but that’s not the point here. A new instance created in java takes some memory space in heap, so creating new objects is always an expensive process.

To avoid this expensive object creation process, many of the frameworks have been evolved during the time, which does specifically resource pooling in different ways. So, it can be understood that having objects ready made has its own benefit and should be promoted as well.

Wrapper classes are immutable in java, Right? “YES”. So, like string pool, they can also have their pool, right? “Great Idea”. Well, it’s already there. JDK provided wrapper classes also provide this in form of instance pooling i.e. each wrapper class store a list of commonly used instances of own type in form of cache and whenever required, you can use them in your code. It helps in saving lots of byes in your program runtime.

Integer cache demonstration

In Integer.java class there is an inner class i.e. IntegerCache. When you assign a new int to Integer type like below:

Integer i = 10; //OR
Integer i = Integer.valueOf(10);

An already created Integer instance is returned and reference is stored in i. Please note that if you use new Integer(10); then a new instance of Integer class will be created and caching will not come into picture. Its only available when you use Integer.valueOf() OR directly primitive assignment (which ultimately uses valueOf() function).

Lets see how this IntegerCache look like in code:

private static class IntegerCache
{
	private IntegerCache(){}
	static final Integer cache[] = new Integer[-(-128) + 127 + 1];
	static {
		for(int i = 0; i < cache.length; i++)
			cache[i] = new Integer(i - 128);
	}
}

And this is how valueOf() method looks like:

public static Integer valueOf(int i)
{
	final int offset = 128;
	if (i >= -128 && i <= 127) // must cache
		return IntegerCache.cache[i + offset];
	}
	return new Integer(i);
}

As you see, IntegerCache is static inner class and will only be initialized when used first time. So on first time, due to cache creation, time might be little longer and after that it will not take more time. But, the actual benefit is memory reuse.

Lets see an example in working:

public class IntegerCacheDemo {

	public static void main(String[] args) {

		Integer a1 = 100;
		Integer a2 = 100;
		Integer a3 = new Integer(100);

		System.out.println(a1 == a2);
		System.out.println(a1 == a3);
	}
}

Output:

true
false

First print statement will print true; means both variables are referring to same instance. But, second print statement prints false, because new Integer(..) created a new fresh instance in separate memory location.So, if you want to make use of this cache, always use primitive assignment to reference variable or use valueOf() method.

Modifying cache size

If you want to store a bigger number of instances, you can use runtime parameter as below:

-Djava.lang.Integer.IntegerCache.high=2000

Above statement will cause the cache to store instances from -127 to 1000. Remember, there is no such property like -Djava.lang.Integer.IntegerCache.low as of now. May be in future, it might be added as well.

Other wrapper classes

In above discussion, I have talked about cache in Integer class, but if fact all wrapper classes provide this facility. lest see them in short:

  1. java.lang.Boolean store two inbuilt instances TRUE and FALSE, and return their reference if new keyword is not used.
  2. java.lang.Character has a cache for chars between unicodes 0 and 127 (ascii-7 / us-ascii).
  3. java.lang.Long has a cache for long between -128 to +127.
  4. java.lang.String has a whole new concept of string pool.

Happy Learning !!

Was this post helpful?

Join 7000+ Fellow Programmers

Subscribe to get new post notifications, industry updates, best practices, and much more. Directly into your inbox, for free.

10 thoughts on “Java Wrapper Classes Internal Caching”

  1. So if I create an Integer array lets say: arr[0]=100, arr[1]=100, arr[2]=100 and now if I do arr[0]++, then all the elements will be incremented?

    Reply
  2. Thank you so much for the article, its compact and easy to understand. Though I have 2 questions
    1. What are the cache instance range for Float and Double Wrapper class?
    2. Are Integer value Integer a1=300; Integer a2=300; a1==a2 will return false?

    Reply
  3. Wrapper Classes are Classes that have written to make objects from the primitive types in Java. They are used to wrap the primitive values in an object. Many thanks for sharing this.

    Reply
  4. Well, In Integer.class, IntegerCache supports instance caching from -128 to 127.
    So, in case we want instance cache support for higher integer values also (lets say 300), we should increase java.lang.Integer.IntegerCache.high value to increase the cache size…

    Is my understanding correct here?

    Reply

Leave a Comment

HowToDoInJava

A blog about Java and its related technologies, the best practices, algorithms, interview questions, scripting languages, and Python.