How != and == operators work on Integers in Java? [duplicate]
Asked Answered
M

5

11

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?

Mallissa answered 22/3, 2012 at 14:14 Comment(2)
This is because the autoboxing mechanism caches and reuses the same object for values in range -128 - 127. This is a duplicate of a previous question.Hydroquinone
#1700581Vicariate
U
10

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.

Underneath answered 22/3, 2012 at 14:17 Comment(2)
The constructor doesn't use caching though. Try: System.out.println(new Integer(2) == new Integer(2))Zeeland
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.Roter
T
4

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

Turboprop answered 22/3, 2012 at 14:16 Comment(1)
@downvoter, would you care to elaborate on your vote?Turboprop
R
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.

Roter answered 22/3, 2012 at 14:24 Comment(1)
Nice to know. Please don't do that in production.Izard
O
0

Java caches integers from -128 to 127 That is why the objects ARE the same.

Orchidectomy answered 22/3, 2012 at 14:18 Comment(0)
L
0

I think the == and != operators when dealing with primitives will work how you're currently using them, but with objects (Integer vs. int) you'll want to perform testing with .equals() method.

I'm not certain on this, but with objects the == will test if one object is the same object or not, while .equals() will perform testing that those two objects contain equivalence in value (or the method will need to be created/overridden) for custom objects.

Lobell answered 22/3, 2012 at 14:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.