DEV Community

Mukul Saini
Mukul Saini

Posted on

Understanding == in Java: Why 1 == 1 is True but 128 == 128 Might Be False

If you’re learning Java, you’ve likely used the== operator countless times. It’s straightforward when dealing with numbers, right? Well, not always. A common point of confusion arises when 1 == 1evaluates to true, but surprisingly, 128 == 128 might evaluate to false. What’s going on? Is Java broken? Absolutely not! The key lies in understanding primitive types, object references, and autoboxing in Java. Let’s unravel this mystery step by step.

Image description

The Basics: Primitive vs Object Comparison
In Java, the == operator behaves differently depending on whether you are comparing primitives or objects:

For primitives(e.g., int, char, double):
The == operator compares the actual values. If the values are the same, the result is true.

int x = 1;
int y = 1;
System.out.println(x == y); // true
Enter fullscreen mode Exit fullscreen mode

For objects (e.g., Integer, String, or custom classes):
The == operator checks whether the two objects point to the same memory location (i.e., reference equality).

Integer x = new Integer(128);
Integer y = new Integer(128);
System.out.println(x == y); // false (different memory locations)
Enter fullscreen mode Exit fullscreen mode

What About Autoboxing?
Java introduced autoboxing in Java 5 to make working with primitives and their wrapper classes (like int and Integer) more seamless. It allows you to write code like this.

Integer a = 1; // Autoboxes the int 1 to an Integer object
int b = a;     // Unboxes the Integer back to a primitive int
Enter fullscreen mode Exit fullscreen mode

While this is convenient, it can lead to subtle bugs when combined with ==. Why? Because objects and primitives behave differently with ==.

The Integer Cache
Java optimizes memory usage by caching Integer objects for values between -128 and 127. This means if you create two Integer objects within this range, they will point to the same memory location. Let’s see this in action.

Integer x = 127;
Integer y = 127;
System.out.println(x == y); // true (same cached object)

Integer a = 128;
Integer b = 128;
System.out.println(a == b); // false (different objects)
Enter fullscreen mode Exit fullscreen mode

When comparing x and y (both 127), Java reuses the same cached object. For a and b (both 128), Java creates two distinct Integer objects outside the cached range. Hence, a == b evaluates to false.

Why Does This Happen?
The caching behavior is defined in the Integer class.

private static class IntegerCache {
   static final Integer[] cache = new Integer[-(-128) + 127 + 1];
   ...
}
Enter fullscreen mode Exit fullscreen mode

By default, Java caches Integer values in the range -128 to 127 to save memory. For numbers outside this range, new objects are created.

How to Avoid This Confusion
If you want to compare the values of two Integer objects (or other wrapper classes), you should use the .equals() method, or explicitly unbox them into primitives.

Using .equals()

Integer a = 128;
Integer b = 128;
System.out.println(a.equals(b)); // true
Enter fullscreen mode Exit fullscreen mode

Unboxing to Primitives

Integer a = 128;
Integer b = 128;
System.out.println(a.intValue() == b.intValue()); // true
Enter fullscreen mode Exit fullscreen mode

Working with Primitives Directly

int a = 128;
int b = 128;
System.out.println(a == b); // true
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

Primitive Comparison: == compares the actual values.

int x = 1, y = 1;
System.out.println(x == y); // true
Enter fullscreen mode Exit fullscreen mode

Object Comparison: == compares memory references, not values.

Integer x = 128, y = 128;
System.out.println(x == y); // false
Enter fullscreen mode Exit fullscreen mode

Integer Cache: Java caches Integer objects for values between -128 and 127.

Integer x

Enter fullscreen mode Exit fullscreen mode

Top comments (0)