Saturday, March 8, 2008

how to create instances of primitive wrapper

I have found out that it can be faster to obtain new instances of primitive wrapper classes such as Integer or Long via the static valueOf method than using the new operator. The reason is that most wrapper classes contain an internal cache of frequently requested instances.

If we take a look at the javaSE 6 source code we can see that the Long class for instance creates a cache inside the static block of an inner class:
private static class LongCache {
private LongCache() { }
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for (int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) {
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}


The main difference is that new will always return a brand new instance whereas the valueOf method may return an “old” object that has been created and cached in advance. The downside of this approach is that the first call of valueOf will create all instance for the cache.

The Double and Float wrapper classes just call new inside the valueOf method. There is no sign of any caching at all in their implementation. All other wrapper classes (Byte, Character, Boolean, ...) have a caching mechanism similar to the example above.

2 comments:

Christian Sadilek said...

Did any incident or problem point you to this? It might make sense to cache the Boolean values but what sense does it make to cache this 256 values of Long? Or am I getting something wrong?

BTW the comment edit control sucks...

Gert Kropiunik said...

Findbugs told me that it would be faster to use the valueOf method so i took a deeper look into the Java SDK source code. I also think that caching Long values does not make much sense because - at least in our application - most of the Long instances that are created are outside the scope of the cached values.