People who program in Java for the first time often find this behavior strange:

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

So why are two variables with the same value sometimes considered equal, and other times not?

The explanation lies in an internal detail of the language called the Integer Cache.

🧠 == does not compare values β€” it compares references

First of all, it's important to remember:

  • == compares references when we're dealing with objects (like Integer);
  • To compare values, the correct method is .equals().

So:

System.out.println(a == b);        // checks if it's the same object
System.out.println(a.equals(b));   // compares the value

πŸ“¦ What is the Integer Cache?

To improve performance and reduce memory allocation, Java maintains an internal cache of Integer objects in the range:

-128 to 127

This means that any autoboxing operation (converting int to Integer) within this range reuses the same object.

For example:

Integer x = 1;
Integer y = 1;

Here, x and y point to the same cached object, so the result is:

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

❗ Outside the range, no cache is applied

Now look at larger values:

Integer a = 1000;
Integer b = 1000;

Since 1000 is outside the -128 to 127 range:

  • a new Integer object is created for a;
  • another new Integer object is created for b.

They do not point to the same reference:

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

πŸ”§ The value comes from Integer.valueOf()

This method:

  • uses the cache for values between -128 and 127;
  • creates a new object outside that range.
| Value range     | Cached? | Result of `==` |
| --------------- | ------- | -------------- |
| -128 to 127     | βœ… Yes   | true          |
| Any other value | ❌ No    | false         |

βœ” Best practice: use .equals()

To avoid unexpected behavior, always compare values like this:

a.equals(b);

Or let Java do unboxing:

a == b.intValue();

🏁 Conclusion

Java's seemingly strange behavior is not a bug β€” it's an optimization.

The Integer Cache helps improve performance and reduce object creation, but it can be confusing when == is used to compare values.

Whenever you're working with numeric objects, remember:

  • == compares references;
  • .equals() compares values.