1==1 is true but 128==128 is false in Java

When comparing two numbers in Java, like 1 == 1 or 128 == 128, it would always return true because, well, it’s the same number on both sides, right? Turns out, it’s not always that simple in Java.

Here’s a little code snippet to illustrate the point:

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

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

In Java, the Integer class has a special optimization called Integer Caching. Java caches Integer objects for values in the range -128 to 127. Why? Well, Java tries to optimize memory usage, and values in this range are pretty commonly used, so instead of creating new objects for each one, it reuses the same ones.

When you do something like this:

Integer x = 1;
Integer y = 1;

Java doesn’t create two separate objects in memory for x and y. Instead, it reuses the cached Integer object for 1. This is why x == y returns true. Both x and y are pointing to the same object in memory.

But when you do:

Integer a = 128;
Integer b = 128;

Since 128 is outside the cached range, Java creates two separate Integer objects. So even though both a and b have the value 128, they are two different objects in memory. That’s why a == b returns false — it’s comparing two different memory locations, not the actual values. 

Breaking It Down — == vs .equals()

Now, this brings up an important distinction. In Java, == compares references, meaning it checks if two variables point to the same object in memory. On the other hand, .equals() compares the values inside those objects.

Let’s tweak the previous code a bit:

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

See the difference? a.equals(b) returns true because it compares the value inside the two Integer objects, which is 128. It doesn’t care about the fact that a and b are pointing to different objects.

The Range -128 to 127

Java caches Integer values in the range -128 to 127. You can think of this range as Java’s sweet spot for saving memory. So, for any integer within this range, Java reuses the same object. For values outside this range, like 128 or 1000, new Integer objects are created each time.

You can even customize this range by setting the JVM argument -XX:AutoBoxCacheMax=size, but by default, it’s fixed at 127.

Example Recap: Here’s a more detailed example with memory addresses:

Integer c = 128;
Integer d = 128;
System.out.println(System.identityHashCode(c)); // Different memory locations
System.out.println(System.identityHashCode(d));

Integer e = 1;
Integer f = 1;
System.out.println(System.identityHashCode(e)); // Same memory location
System.out.println(System.identityHashCode(f));

Output might look like this:

212628335
2111991224
false
292938459
292938459
true

For values in the -128 to 127 range, you’ll see the same memory address, but for values outside that range (like 128), Java allocates different memory locations.

Why This Matters?

This behavior could lead to unexpected results if you’re comparing numbers using == instead of .equals() in your code, especially for values outside the cached range. So the takeaway here? Use .equals() when comparing object values, unless you specifically need to compare memory locations (which is rare in most applications).

Java’s Integer caching is one of those nifty little optimizations that works great most of the time. But once you move out of the -128 to 127 range, things can get tricky if you’re relying on == to compare numbers. Just remember to use .equals() for values and you’re good to go!

Post a Comment

Previous Post Next Post