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 == 1
evaluates 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.
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
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)
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
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)
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];
...
}
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
Unboxing to Primitives
Integer a = 128;
Integer b = 128;
System.out.println(a.intValue() == b.intValue()); // true
Working with Primitives Directly
int a = 128;
int b = 128;
System.out.println(a == b); // true
Key Takeaways
Primitive Comparison: ==
compares the actual values.
int x = 1, y = 1;
System.out.println(x == y); // true
Object Comparison: ==
compares memory references, not values.
Integer x = 128, y = 128;
System.out.println(x == y); // false
Integer Cache: Java caches Integer objects for values between -128
and 127
.
Integer x
Top comments (0)