33

I got a very strange problem when I'm trying to compare 2 Long variables, they always show false and I can be sure they have the same number value by debugging in Eclipse:

if (user.getId() == admin.getId()) {
    return true; // Always enter here
} else {
    return false;
}

Both of above 2 return values are object-type Long, which confused me. And to verify that I wrote a main method like this:

Long id1 = 123L;
Long id2 = 123L;

System.out.println(id1 == id2);

It prints true.

So can somebody give me ideas?. I've been working in Java Development for 3 years but cannot explain this case.

hongsy
  • 1,498
  • 1
  • 27
  • 39
Brady Zhu
  • 1,305
  • 5
  • 21
  • 43
  • 4
    It depends on the size of the Long. Smaller Longs and Integers are interred and are truly identical objects, but longer ones are not, and for these you will need to use `.equals(...)` or unbox them. – Hovercraft Full Of Eels Oct 21 '13 at 03:29

3 Answers3

55

== compares references, .equals() compares values. These two Longs are objects, therefore object references are compared when using == operator.

However, note that in Long id1 = 123L; literal value 123L will be auto-boxed into a Long object using Long.valueOf(String), and internally, this process will use a LongCache which has a [-128,127] range, and 123 is in this range, which means, that the long object is cached, and these two are actually the same objects.

Giorgi Tsiklauri
  • 9,715
  • 8
  • 45
  • 66
BlackJoker
  • 3,099
  • 2
  • 20
  • 27
  • in my case, the returned ID value is 16 which is not exceeded to its range. – Brady Zhu Oct 21 '13 at 03:36
  • yeah,but those Longs may not created by Long.valueOf(),meigh be new Long(12),so,they are different objects. – BlackJoker Oct 21 '13 at 03:45
  • 1
    Runtime implementations are guaranteed to cache `Integer` values -128..127. Values outside that range, or of any other numeric type (e.g. `Long`), may be cached if the runtime happens to notice that doing so would be advantageous in a particular case, but the spec says nothing about what advantageous cases the runtime will or will not recognize. – supercat Oct 21 '13 at 16:59
9

because == compares reference value, and smaller long values are cached

 public static Long  valueOf(long l) {
     final int offset = 128;
     if (l >= -128 && l <= 127) { // will cache
         return LongCache.cache[(int)l + offset];
     }
     return new Long(l);
 }

so it works for smaller long values

Also See

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
3

Stuck on an issue for 4 hours because of the use of == ... The comparison was ok on Long < 128 but ko on greater values.

Generally it's not a good idea to use == to compare Objects, use .equals() as much as possible ! Keep ==, >, <, <= etc. for primitives.

Thibault
  • 1,049
  • 9
  • 7