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:
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:
Conversely, for values outside this range, such as 128, Java creates a new Integer object each time:
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
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 intrue.
Recommended Practice
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:
Summary Table
| Description | Example Code | Evaluation (using ==) | Evaluation (using equals()) |
| Cached Integer comparison | Integer x = 127;
Integer y = 127; | x == y is true | x.equals(y) is true |
| Non-cached Integer comparison | Integer a = 128;
Integer b = 128; | a == b is false | a.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:
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.

