7

I have this Java code:

public class Foo {
    public static void main(String[] args) {
         Integer x = 5;
         Integer y = 5;
         System.out.println(x == y);
    }
}

Is it guaranteed to print true on the console? I mean, is it comparing the two boxed integers by value (which is what I need to do) or by reference identity?

Also, will it be any different if I cast them to unboxed integers like this

public class Foo {
    public static void main(String[] args) {
         Integer x = 5;
         Integer y = 5;
         System.out.println((int) x == (int) y);
    }
}
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
oggioniw
  • 95
  • 1
  • 6
  • 5
    It is comparing them by reference identity. Integers in the range `-128` to `127` are cached, which is why Integer instances are sometimes the same reference. But you are better off using `equals`. – khelwood Mar 14 '19 at 16:14
  • It will work but is highly discouraged. Compare literals with `==`. Compare objects with `equals()` – Arnaud Denoyelle Mar 14 '19 at 16:14
  • 1
    the thing is that if I write `(int) x == (int) y` the IDE (I'm using intellijIdea) tells me that the cast is unnnecessary – oggioniw Mar 14 '19 at 16:15
  • @khelwood They will be the same. Caching is documented behavior. – shmosel Mar 14 '19 at 16:17
  • 1
    If needed you can do `x.intValue() == y.intValue()`, but it is better to just use `x.equals(y)` – Andreas Mar 14 '19 at 16:17
  • @shmosel Yes, they will be the same in this specific case. In general two integers of the same value _might_ be the same but are not necessarily. – khelwood Mar 14 '19 at 16:19
  • @Andreas what if one of them is `null` and the other is `0`? – oggioniw Mar 14 '19 at 16:21
  • 4
    @oggioniw If either might be null, you need to null-check it (or use [`Objects.equals`](https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#equals(java.lang.Object,%20java.lang.Object))). Using `.equals` or `.intValue()` or `(int)` *all* risk raising a `NullPointerException`. – khelwood Mar 14 '19 at 16:22
  • 1
    @khelwood +1 for suggesting usage of [Objects.equals](https://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#equals(java.lang.Object,%20java.lang.Object)) – oggioniw Mar 14 '19 at 16:26

2 Answers2

15

No, it's not the right way to compare the Integer objects. You should use Integer.equals() or Integer.compareTo() method.

By default JVM will cache the Integer values from [-128, 127] range (see java.lang.Integer.IntegerCache.high property) but other values won't be cached:

Integer x = 5000;
Integer y = 5000;
System.out.println(x == y); // false

Unboxing to int or calling Integer.intValue() will create an int primitive that can be safely compared with == operator. However unboxing a null will result in NullPointerException.

Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
  • what if I cast them to unboxed integers like this `(int) x == (int) y`? – oggioniw Mar 14 '19 at 16:22
  • 1
    For full answer, mention use of `Objects.equals` as [commented by khelwood](https://stackoverflow.com/questions/55167297/is-it-safe-to-compare-two-integer-values-with-in-java?noredirect=1#comment97074301_55167297) as solution to null issue. – Andreas Mar 14 '19 at 16:27
  • 1
    Also cache range is configurable since Java7 – Antoniossss Mar 14 '19 at 16:35
0

No it is not the right way to compare to object directly.You can convert to int value and compare.

Java implementation

Where value is of type int.

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
gati sahu
  • 2,576
  • 2
  • 10
  • 16