Why equal operator works for Integer value until 128 number?

18,505

Solution 1

Check out the source code of Integer . You can see the caching of values there.

The caching happens only if you use Integer.valueOf(int), not if you use new Integer(int). The autoboxing used by you uses Integer.valueOf.

According to the JLS, you can always count on the fact that for values between -128 and 127, you get the identical Integer objects after autoboxing, and on some implementations you might get identical objects even for higher values.

Actually in Java 7 (and I think in newer versions of Java 6), the implementation of the IntegerCache class has changed, and the upper bound is no longer hardcoded, but it is configurable via the property "java.lang.Integer.IntegerCache.high", so if you run your program with the VM parameter -Djava.lang.Integer.IntegerCache.high=1000, you get "Same values" for all values.

But the JLS still guarantees it only until 127:

Ideally, boxing a given primitive value p, would always yield an identical reference. In practice, this may not be feasible using existing implementation techniques. The rules above are a pragmatic compromise. The final clause above requires that certain common values always be boxed into indistinguishable objects. The implementation may cache these, lazily or eagerly.

For other values, this formulation disallows any assumptions about the identity of the boxed values on the programmer's part. This would allow (but not require) sharing of some or all of these references.

This ensures that in most common cases, the behavior will be the desired one, without imposing an undue performance penalty, especially on small devices. Less memory-limited implementations might, for example, cache all characters and shorts, as well as integers and longs in the range of -32K - +32K.

Solution 2

According to Java Language Specifications:

If the value p being boxed is true, false, a byte, a char in the range \u0000 to \u007f, or an int or short number between -128 and 127, then let r1 and r2 be the results of any two boxing conversions of p. It is always the case that r1 == r2.

JLS Boxing Conversions

Refer to this article for more information on int caching

Solution 3

Integer is a wrapper class for int.

Integer != Integer compares the actual object reference, where int != int will compare the values.

As already stated, values -128 to 127 are cached, so the same objects are returned for those.

If outside that range, separate objects will be created so the reference will be different.

To fix it:

  • Make the types int or
  • Cast the types to int or
  • Use .equals()

Solution 4

The Integer object has an internal cache mechanism:

private static class IntegerCache {
    static final int high;
    static final Integer cache[];

    static {
        final int low = -128;

        // high value may be configured by property
        int h = 127;
        if (integerCacheHighPropValue != null) {
            // Use Long.decode here to avoid invoking methods that
            // require Integer's autoboxing cache to be initialized
            int i = Long.decode(integerCacheHighPropValue).intValue();
            i = Math.max(i, 127);
            // Maximum array size is Integer.MAX_VALUE
            h = Math.min(i, Integer.MAX_VALUE - -low);
        }
        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() {}
}

Also see valueOf method:

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

This is why you should use valueOf instead of new Integer. Autoboxing uses this cache.

Also see this post: https://effective-java.com/2010/01/java-performance-tuning-with-maximizing-integer-valueofint/

Using == is not a good idea, use equals to compare the values.

Solution 5

Use .equals() instead of ==.

Integer values are only cached for numbers between -127 and 128, because they are used most often.

if (a.equals(b)) { ... }
Share:
18,505

Related videos on Youtube

gokhansari
Author by

gokhansari

Updated on June 16, 2022

Comments

  • gokhansari
    gokhansari almost 2 years

    Why Integer == operator does not work for 128 and after Integer values? Can someone explain this situation?

    This is my Java environment:

    java version "1.6.0_37"
    Java(TM) SE Runtime Environment (build 1.6.0_37-b06)
    Java HotSpot(TM) 64-Bit Server VM (build 20.12-b01, mixed mode)
    

    Sample Code:

    Integer a;
    Integer b;
    a = 129;
    b = 129;
    
    for (int i = 0; i < 200; i++) {
        a = i;
        b = i;
    
        if (a != b) {
            System.out.println("Value:" + i + " - Different values");
        } else {
            System.out.println("Value:" + i + " - Same values");
        }
    }
    

    Some part of console output:

    Value:124 - Same values
    Value:125 - Same values
    Value:126 - Same values
    Value:127 - Same values
    Value:128 - Different values
    Value:129 - Different values
    Value:130 - Different values
    Value:131 - Different values
    Value:132 - Different values
    
  • lbalazscs
    lbalazscs about 11 years
    This answer is wrong, it has to do nothing with the hotspot jvm, the caching is implemented in the source code of Integer,
  • Denis Rosca
    Denis Rosca about 11 years
    @lbalazscs as far as I know the values that are cached are jvm dependent. I think this caching is specified in the java language spec, but the values to be cached are not specified. This is why I mentioned the hotspot jvm. Is this not correct?
  • Marko Topolnik
    Marko Topolnik about 11 years
    It is not correct. Why don't you have a look at the source code of java.lang.Integer, for example.
  • Christophe Roussy
    Christophe Roussy about 11 years
    Not correct, it is related to the implementation of java.lang.Integer
  • lbalazscs
    lbalazscs about 11 years
    The documentation of Integer.valueOf (and not the JLS) mentions that this method could use caching.
  • Denis Rosca
    Denis Rosca about 11 years
    @lbalazscs actually the jls specifies that. But I admit that my answer is a little misleading. I'll edit it.
  • lbalazscs
    lbalazscs about 11 years
    OK, the JLS also mentions caching. But unless you show me the caching in the source code of the JVM, I really don't think that they implemented a second caching there, if there is already one in the source code of Integer...
  • Denis Rosca
    Denis Rosca about 11 years
    @lbalazscs I aggree, my comment about the jvm was misleading, although the same jls states that different implementations can cache more values if they are not resource constrained.