Card 05/ 08
Flyweight in the Wild: Java's Integer.valueOf Cache
Integer.valueOf(100) returns the same object twice; Integer.valueOf(1000) does not.
Java's Integer.valueOf is a flyweight factory built into the JDK. Small integers are used constantly as boxed Integer objects, so the class keeps a cache of them and returns the stored object instead of creating a new one. This card asks you to predict which calls share an object, then shows the range the cache covers.
== on two objects in Java is true only when both references point to the same object. Four comparisons follow, each between two calls to Integer.valueOf with the same number.
Integer.valueOf(100) == Integer.valueOf(100)
Integer.valueOf(1000) == Integer.valueOf(1000)
Integer.valueOf(127) == Integer.valueOf(127)
Integer.valueOf(128) == Integer.valueOf(128)Which of the four are true? Decide, then look.
public class FlInteger {
public static void main(String[] args) {
System.out.println("valueOf(100) twice, same object: " + (Integer.valueOf(100) == Integer.valueOf(100)));
System.out.println("valueOf(1000) twice, same object: " + (Integer.valueOf(1000) == Integer.valueOf(1000)));
System.out.println("valueOf(127) twice, same object: " + (Integer.valueOf(127) == Integer.valueOf(127)));
System.out.println("valueOf(128) twice, same object: " + (Integer.valueOf(128) == Integer.valueOf(128)));
System.out.println("java " + System.getProperty("java.version"));
}
}valueOf(100) twice, same object: true
valueOf(1000) twice, same object: false
valueOf(127) twice, same object: true
valueOf(128) twice, same object: false
java 21.0.12100 and 127 return a shared object; 1000 and 128 return two new ones. The Integer.valueOf documentation guarantees a cache from -128 to 127, and the run in eclipse-temurin:21-jdk, Java 21.0.12, agrees.
The JDK's factory has the same parts as the template: the key is the number, the pool is an array of pre-built Integer objects, and an Integer is immutable, so sharing it is safe. The upper bound can be raised with the -XX:AutoBoxCacheMax option, and a run with it set to 2000 made the comparison of two 1000s true.
The same mechanism serves autoboxing, where Java turns an int into an Integer without being asked, because the compiler writes a call to Integer.valueOf. That is the route by which the cache reaches ordinary code, usually without the programmer noticing.
← → move through sections and cards