Why Java Integer Autoboxing Returns the Same Object for Values 0‑127 and How to Compare Correctly
This article explains Java's integer autoboxing cache, why the == operator returns true for Integer objects between -128 and 127, shows the underlying source code, and recommends using equals() for value comparison, with detailed examples and code snippets.
Preface – After Java 5 introduced autoboxing and unboxing, many developers encounter a puzzling behavior where comparing two Integer objects with == yields true for small values but false for larger ones. The article records the issue to avoid future mistakes.
Problem Description
Example 1
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));
}
}Running this prints true for i = 0‑127 and false from 128 onward.
Example 2
public static void main(String[] args) {
Map
mapA = new HashMap<>();
Map
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 shows the same true/false pattern.
Analysis – Autoboxing
Autoboxing converts a primitive int to an Integer by calling Integer.valueOf(i) . For values between -128 and 127, valueOf returns a cached object instead of creating a new one.
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}The cache is populated in the static block of the inner class IntegerCache :
private static final class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
int h = 127;
// optional property handling omitted for brevity
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, for -128 ≤ i ≤ 127 the same cached Integer instance is returned, making a == b true. Outside this range a new object is created each time, so a == b becomes false.
Solution
Since == checks 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 values.
Note
All eight primitive types in Java have corresponding wrapper classes that also use caching for certain ranges (e.g., Byte , Short , Long , Character ), which can lead to similar identity‑comparison surprises.
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.