Java
Integer Wrapper
Autoboxing
Equality
Java Puzzles

Why is 128128 false but 127127 is true when comparing Integer wrappers in Java?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In Java, handling integers and their comparisons can sometimes lead to surprising behavior when working with Integer wrappers. One such surprise is the peculiar behavior of the == operator when comparing Integer objects. This inconsistency is seen when comparing Integer wrappers of values 128 and beyond, versus values within the range of -128 to 127. This article will explore the reasons behind why 128 == 128 evaluates to false but 127 == 127 evaluates to true when comparing Integer wrappers in Java.

Autoboxing and the Integer Cache

The key to understanding this behavior lies in Java's treatment of Integer objects through a mechanism known as autoboxing and an internal cache for small integer values.

Autoboxing

Introduced in Java 5, autoboxing automatically converts between primitive types and their corresponding object wrapper classes. For example, when you assign an int to an Integer object, Java performs autoboxing:

java
Integer a = 128; // Autoboxes int 128 to Integer

Integer Cache

To optimize memory usage and performance, Java maintains a cache of Integer objects for values ranging from -128 to 127. This means that whenever an Integer object is created with a value within this range through autoboxing or other factory methods, it reuses a pre-existing instance instead of creating a new one. For instance:

java
Integer x = 127;
Integer y = 127;
// x and y refer to the same Integer object

Conversely, for values outside this range, such as 128, Java creates a new Integer object each time:

java
Integer a = 128;
Integer b = 128;
// a and b are different Integer objects

The == Operator and Object Equality

The == operator in Java, when used with object references, checks for reference equality rather than object content equality. This can lead to confusing results when you're comparing Integer objects beyond the cached range:

Example Code

java
1// True for cached integers
2Integer x = 127;
3Integer y = 127;
4boolean result1 = (x == y); // true
5
6// False for integers outside the cached range
7Integer a = 128;
8Integer b = 128;
9boolean result2 = (a == b); // false
10
11// True when using equals()
12boolean result3 = a.equals(b); // true

Why 128 == 128 is false

When 128 == 128 is evaluated for Integer objects, it returns false because:

  • Two distinct Integer objects are created for value 128, as it falls outside the cache range.
  • The == operator checks if both references point to the same object, which they do not.

Why 127 == 127 is true

Conversely, when comparing Integer objects with the value 127:

  • A cached Integer object reference is reused.
  • Both references point to the same object, so == results in true.

Due to this subtlety in behavior, it is always recommended to use the equals() method for comparing Integer objects in Java. This ensures that content equality rather than reference equality is checked:

java
1// Always use equals() for object comparison
2Integer a = 128;
3Integer b = 128;
4boolean isEqual = a.equals(b); // true

Summary Table

DescriptionExample CodeEvaluation (using ==)Evaluation (using equals())
Cached Integer comparisonInteger x = 127; Integer y = 127;x == y is truex.equals(y) is true
Non-cached Integer comparisonInteger a = 128; Integer b = 128;a == b is falsea.equals(b) is true

Additional Details

Customizing the Cache Size

Beginning with Java 1.7, the range of the Integer cache can be adjusted using the JVM option -XX:AutoBoxCacheMax=<size> to change the upper limit of the cache size:

bash
java -XX:AutoBoxCacheMax=1000 MyProgram

This feature can be helpful in scenarios where the application frequently uses larger integer values and object creation overhead must be minimized.

Conclusion

Understanding the behavior of autoboxing and the Integer cache in Java is crucial for avoiding bugs related to the misuse of the == operator with Integer objects. Adopting the practice of using the equals() method ensures accurate comparisons and reliable code. While Java manages integers efficiently, knowing the underlying mechanisms allows developers to write more optimized and predictable programs.


Course illustration
Course illustration

All Rights Reserved.