Back to Blog
Why `1 == 1` is True but `128 == 128` is False in Java — The Integer Caching Trap Explained
Java Tips

Why `1 == 1` is True but `128 == 128` is False in Java — The Integer Caching Trap Explained

Discover the surprising behavior behind Java's Integer caching mechanism and why `==` comparisons can lead to unexpected results.

22 viewsJuly 21, 20253 min readRabi
javaintegercachingjava-tipsjava-interviewobject-comparisonautoboxing

Ever written a simple Java comparison like Integer a = 128; Integer b = 128; and got surprised that a == b returned false? 🤯 You're not alone.

Let’s unravel this fascinating corner of the Java language where autoboxing, object pooling, and reference comparison collide in unexpected ways.

🧠 The Unexpected Behavior

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false
 
Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true

At first glance, both a and b are Integer objects with the same value. So why does a == b return false, while x == y returns true?

Short Answer:

Java caches Integer objects from -128 to 127. Outside that range, new objects are created — even if the values are the same.

🔍 What's Happening Behind the Scenes?

In Java, Integer is a wrapper class, and assigning int to Integer uses autoboxing. When you do:

Integer x = 1;

Java checks if that number is in the cache. If it is, it reuses the object. This makes:

Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true ✅

Because both point to the same object in memory.

But if the value is outside -128 to 127:

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false ❌

New Integer objects are created each time, so a and b point to different memory locations.

🧪 Use .equals() for Value Comparison

Unlike == which checks reference equality, .equals() compares the actual values:

Integer a = 128;
Integer b = 128;
System.out.println(a.equals(b)); // true ✅

Always use .equals() when comparing wrapper objects or values from unknown sources.

💡 Customizing the Cache (Advanced)

You can tweak the cache range by setting a JVM option:

-XX:AutoBoxCacheMax=256

This increases the upper bound of cached values. Note: this works only for Integer, not other wrappers.

🔬 Memory Check Example with System.identityHashCode()

To prove that cached and non-cached Integers are different objects:

Integer c = 128;
Integer d = 128;
System.out.println(System.identityHashCode(c));
System.out.println(System.identityHashCode(d));
 
Integer e = 1;
Integer f = 1;
System.out.println(System.identityHashCode(e));
System.out.println(System.identityHashCode(f));

You'll observe that:

  • c and d have different hash codes (not cached)
  • e and f have same hash code (cached)

🚨 Why This Matters in Real Projects

This behavior can cause hard-to-find bugs when developers rely on == for wrapper classes. Some common issues:

  • Comparing response values from APIs or databases
  • Conditional logic failures in object comparisons
  • Test assertions failing unexpectedly

✅ Best Practice: Always Use .equals()

Use .equals() when comparing:

  • Boxed types (Integer, Long, etc.)
  • Objects from user input or external systems

Use == only when:

  • Comparing primitives (int, long, etc.)
  • Checking for exact same object instance (rare)

🎯 Key Takeaways

  • Java caches Integer values from -128 to 127.
  • == compares references, not values.
  • .equals() is the correct way to compare object values.
  • Autoboxing can introduce subtle bugs if not understood well.

Did this save you from a bug? Hit that bookmark or share it with your Java buddies!

Want more Java mysteries decoded? Follow me on GitHub or connect on Instagram. ☕

Liked the blog?

Share it with your friends and help them learn something new!