Why Java’s Autoboxing Can Surprise You: Integer Cache, Pitfalls, and Performance
This article explains Java autoboxing and unboxing, the hidden IntegerCache mechanism, common comparison traps, null‑pointer risks, and performance overhead, providing code examples and interview‑style Q&A to deepen understanding of these language features.
Key Concepts
Autoboxing and unboxing were introduced in Java 5 as syntactic sugar that automatically converts between primitive types and their wrapper classes.
1. How Autoboxing/Unboxing Works
Integer a = 100; // autoboxing
int b = a; // unboxingThe compiler rewrites this as:
Integer a = Integer.valueOf(100);
int b = a.intValue();2. IntegerCache Mechanism
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}By default the cache covers -128 to 127; the upper bound can be increased with the JVM option -XX:AutoBoxCacheMax=<size>. Values inside the range are pre‑created at class loading, so valueOf() returns a cached instance instead of allocating a new object.
Example:
Integer x = 127;
Integer y = 127;
System.out.println(x == y); // true (same cached object)
Integer m = 128;
Integer n = 128;
System.out.println(m == n); // false (different objects)
System.out.println(m.equals(n)); // true (same value)3. Cache Ranges for Primitive Wrappers
Byte: -128 ~ 127 (all values) Short: -128 ~ 127 Integer: -128 ~ 127 (high bound configurable) Long: -128 ~ 127 Character: 0 ~ 127 Boolean: true / false Double, Float: no cache
4. Common Pitfalls
Using == to compare wrapper objects checks reference equality and only yields true for cached values; always use equals() for value comparison to avoid non‑portable behavior.
5. NullPointerException from Unboxing
Integer count = null;
int total = count + 1; // NPE because count.intValue() is invokedWhen a wrapper may be null (e.g., values from a map or method return), perform a null check before unboxing.
6. Performance Overhead
// Performance trap: each iteration creates a temporary Long object
Long sum = 0L;
for (long i = 0; i < 1_000_000; i++) {
sum += i; // equivalent to sum = Long.valueOf(sum.longValue() + i)
}
// Better: use a primitive long
long sum = 0L;Interview Q&A
Q: What is the difference between new Integer(100) and Integer a = 100?
A: The former always creates a new object, bypassing the cache; the latter calls Integer.valueOf() and may return a cached instance for values within -128 ~ 127. The constructor was deprecated in Java 9.
Q: Does the == operator trigger unboxing?
A: Between two wrapper objects, == compares references and does not unbox. Between a wrapper and a primitive, it unboxes the wrapper and compares the primitive values.
Q: How can the current IntegerCache.high value be inspected?
A: Use reflection on java.lang.Integer$IntegerCache to read the high field, or view JVM flags with -XX:+PrintFlagsFinal.
Autoboxing is syntactic sugar that calls valueOf() ; unboxing calls intValue() (or similar) to restore the primitive. The integer cache (‑128 ~ 127) is the main hidden trap— == on wrappers may give unexpected results, so prefer equals() and guard against null before unboxing.
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
