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.

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

Join the Community

Get the latest articles on system design, frontend & backend development, and emerging tech trends delivered straight to your inbox.

No spam. Unsubscribe at any time.

Liked the blog?

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