How != and == operators work on Integers in Java?

11,277

Solution 1

Integers are cached for values between -128 and 127 so Integer i = 127 will always return the same reference. Integer j = 128 will not necessarily do so. You will then need to use equals to test for equality of the underlying int.

This is part of the Java Language Specification:

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

But 2 calls to Integer j = 128 might return the same reference (not guaranteed):

Less memory-limited implementations might, for example, cache all char and short values, as well as int and long values in the range of -32K to +32K.

Solution 2

Because small integers are interned in Java, and you tried the numbers on different sides of the "smallness" limit.

Solution 3

There exist an Integer object cache from -128 and up to 127 by default. The upper border can be configured. The upper cache border can be controlled by VM option -XX:AutoBoxCacheMax=<size>

You are using this cache when you use the form:

 Integer i1 = 127;

or

Integer i1 = Integer.valueOf(127);

But when you use

Integer i1 = new Integer(127);

then you're guaranteed to get a new uncached object. In the latter case both versions print out the same results. Using the cached versions they may differ.

Share:
11,277
Debadyuti Maiti
Author by

Debadyuti Maiti

Student of Computer Science.

Updated on June 03, 2022

Comments

  • Debadyuti Maiti
    Debadyuti Maiti almost 2 years

    The following code seemed really confusing to me since it provided two different outputs.The code was tested on jdk 1.7.

    public class NotEq {
    
    public static void main(String[] args) {
    
        ver1();
        System.out.println();
        ver2();
    }
    
    public static void ver1() {
        Integer a = 128;
        Integer b = 128;
    
        if (a == b) {
            System.out.println("Equal Object");
        }
    
        if (a != b) {
            System.out.println("Different objects");
        }
    
        if (a.equals(b)) {
            System.out.println("Meaningfully equal.");
        }
    }
    
    public static void ver2() {
        Integer i1 = 127;
        Integer i2 = 127;
        if (i1 == i2) {
            System.out.println("Equal Object");
        }
    
        if (i1 != i2){
            System.out.println("Different objects");
        }
        if (i1.equals(i2)){
            System.out.println("Meaningfully equal");
        }
    }
    
    }
    

    Output:

    [ver1 output]
    Different objects
    Meaningfully equal.

    [ver2 output]
    Equal Object
    Meaningfully equal

    Why the == and != testing produces different results for ver1() and ver2() for same number much less than the Integer.MAX_VALUE? Can it be concluded that == checking for numbers greater than 127 (for wrapper classes like Integer as shown in the code) is totally waste of time?

  • fgb
    fgb about 12 years
    The constructor doesn't use caching though. Try: System.out.println(new Integer(2) == new Integer(2))
  • Fabian Barney
    Fabian Barney about 12 years
    new Integer(127) will never return the same reference. In fact, it guarantees to always create a new object. But when auto-boxing is used like in Integer i = 127; then the cache is used. Btw the upper border 127 is not fixed but a minimum. It can be configured to a larger value but not lower.
  • Sergey Kalinichenko
    Sergey Kalinichenko about 12 years
    @downvoter, would you care to elaborate on your vote?
  • atamanroman
    atamanroman about 9 years
    Nice to know. Please don't do that in production.