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<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 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.
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.
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.
