Fundamentals 7 min read

Understanding Integer and String Comparison in Java: Autoboxing, Caching, and Equality

This article explains why Java's Integer and String objects behave differently when compared with ==, covering autoboxing, the Integer cache range, string constant pool behavior, and the effects of unboxing on equality checks.

Java Captain
Java Captain
Java Captain
Understanding Integer and String Comparison in Java: Autoboxing, Caching, and Equality

Most programmers lack deep technical knowledge, but senior engineers are expected to understand subtleties such as object identity in Java. This article demonstrates common pitfalls when using the == operator with Integer and String objects.

Integer comparison

Consider the following code:

public static void main(String[] args) {
    Integer a = 128, b = 128;
    Integer c = 127, d = 127;
    System.out.println(a == b);
    System.out.println(c == d);
}

The output is false for a == b and true for c == d . The reason lies in the IntegerCache used by the valueOf method, which caches values in the range -128 to 127 . Values outside this range are allocated as new objects.

/**
 * Cache to support the object identity semantics of autoboxing for values between
 * -128 and 127 (inclusive) as required by JLS.
 * The cache size may be controlled by the -XX:AutoBoxCacheMax=<size> option.
 */
private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];
    static {
        int h = 127;
        String prop = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (prop != null) {
            int i = Integer.parseInt(prop);
            i = Math.max(i, 127);
            h = Math.min(i, Integer.MAX_VALUE - (-low) - 1);
        }
        high = h;
        cache = new Integer[(high - low) + 1];
        int j = low;
        for (int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);
    }
    private IntegerCache() {}
}

The valueOf(int i) method returns a cached instance when the argument falls within the cache range:

public static Integer valueOf(int i) {
    assert IntegerCache.high >= 127;
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

String comparison

Now examine this code:

public static void main(String[] args) {
    String s1 = "abc";
    String s2 = "abc";
    String s3 = new String("abc");
    System.out.println(s1 == s2);
    System.out.println(s1 == s3);
}

Because string literals are stored in the string constant pool, s1 and s2 reference the same pooled object, so the first comparison prints true . s3 is created with new , allocating a distinct object on the heap, making the second comparison print false .

Integer vs. int comparison

Finally, consider:

public static void main(String[] args) {
    Integer a = new Integer(128);
    int b = 128;
    Integer c = new Integer(6);
    Integer d = new Integer(6);
    System.out.println(a == b);
    System.out.println(c == d);
}

When an Integer is compared to an int> using == , the Integer is unboxed to a primitive, so a == b evaluates to true . The comparison c == d is between two distinct objects created with new , resulting in false .

Understanding these mechanisms helps avoid subtle bugs and demonstrates why senior developers are expected to grasp Java's caching and identity semantics.

JavaProgrammingcachingString()autoboxingEqualityInteger
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.