Why Does Java’s Integer Autoboxing Return the Same Object for 0‑127?
This article explains why Java’s Integer autoboxing caches values between -128 and 127, causing the == operator to report true for those numbers, and shows how to avoid the pitfall by using equals() instead.
Introduction
This issue commonly appears after Java 5 introduced autoboxing and unboxing, confusing many developers when object comparison behaves unexpectedly.
Problem Description
Example 1
A simple loop creates two Integer objects from the same int value and prints the result of a == b:
public static void main(String[] args) {
for (int i = 0; i < 150; i++) {
Integer a = i;
Integer b = i;
System.out.println(i + " " + (a == b));
}
}The output shows true for 0‑127 and false from 128 onward.
Example 2
The same comparison is performed with values stored in two maps:
public static void main(String[] args) {
Map<Integer, Integer> mapA = new HashMap<>();
Map<Integer, Integer> mapB = new HashMap<>();
for (int i = 0; i < 150; i++) {
mapA.put(i, i);
mapB.put(i, i);
}
for (int i = 0; i < 150; i++) {
System.out.println(i + " " + (mapA.get(i) == mapB.get(i)));
}
}It yields the same pattern of true up to 127 and false afterwards.
Why do both examples show equality up to 127 and inequality from 128?
Analysis of Autoboxing
Autoboxing
When assigning an int to an Integer, the compiler inserts a call to Integer.valueOf(int):
Integer a = Integer.valueOf(1);This method either returns a cached object or creates a new one.
Is It the Same Object?
Printing the identity hash codes of a and b reveals that for 0‑127 the two references share the same hash code, while from 128 onward they differ:
for (int i = 0; i < 150; i++) {
Integer a = i;
Integer b = i;
System.out.println(i + " " + System.identityHashCode(a) + " " + System.identityHashCode(b));
}This demonstrates that Java caches Integer objects in the range -128 to 127.
Looking at the Source Code
The Integer.valueOf implementation shows the caching logic:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}The nested IntegerCache class pre‑creates an array of Integer objects for the range -128 to 127 during class initialization:
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
int h = 127;
// optional high value can be set via system property
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for (int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
}Thus, values within the cached range return the same object, making == true.
Solution
Since == compares object identity, use equals() to compare the numeric values of Integer objects:
for (int i = 0; i < 150; i++) {
Integer a = i;
Integer b = i;
System.out.println(i + " " + a.equals(b));
}This prints true for all iterations.
Additional Note
All eight primitive wrapper classes in Java employ similar caching strategies for certain values. The following image summarizes the cached ranges:
Reference
Official Java SE documentation.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Interview Crash Guide
Dedicated to sharing Java interview Q&A; follow and reply "java" to receive a free premium Java interview guide.
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.
