-3

Consider:

Integer i = 11;
Integer j = 11;
Integer h = 10000;
Integer k = 10000;
System.out.println((i==j));
System.out.println((i.equals(j)));
System.out.println((h==k));
System.out.println((h.equals(k)));

The output is:

true
true
false
true

Actually for h==k, it should also give true. What is the explanation?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Nisrin Dhoondia
  • 145
  • 1
  • 10

1 Answers1

1

Because == checks object references while equals checks actual values. They are not guaranteed to yield the same result.

In some cases they do give the same result, but that's because your JVM is interning some of the Integer objects. Meaning, it maintains a cache of integer objects. So for example if you ask for an Integer value of 10, it might return the same object instance. But there are no guarantees as to which values would be interned. So it is always advisable to use equals instead of relying on ==.

curlyBraces
  • 1,095
  • 8
  • 12
  • So up to which max Integer value it will return the same object instance for ==. – Nisrin Dhoondia Sep 17 '18 at 03:19
  • @NisrinDhoondia - Nope. The limit is -256 to +255 by default (IIRC). And that is only if you use `Integer.valueOf(int)` to generate your `Integer` values. If you use `new Integer(int)` you get a distinct (non-interned) `Integer` object every time. – Stephen C Sep 17 '18 at 03:21
  • @StephenC modified the answer to make it clear. – curlyBraces Sep 17 '18 at 03:22
  • 2
    @NisrinDhoondia actually the limit on my JVM is -128 to 127. But again this is not part of the language specification, so you cannot rely on this behaviour. – curlyBraces Sep 17 '18 at 03:23
  • 2
    (My memory ... pfff!) Actually, there is an obscure JVM option that changes the range of the `Integer` cache. And I should have mentioned that autoboxing uses `valueOf`. – Stephen C Sep 17 '18 at 03:24
  • Yep: https://stackoverflow.com/q/15052216/7294647 – Jacob G. Sep 17 '18 at 03:27
  • (And the range -128 to +127 >>is<< guaranteed by the JLS - https://docs.oracle.com/javase/specs/jls/se10/html/jls-5.html#jls-5.1.7. But only for the Boxing conversion.) – Stephen C Sep 17 '18 at 03:30
  • @StephenC, good to know. But since it is overridable by JVM option, how can one be sure what are the actual values in a running JVM. Better to use `equals`. – curlyBraces Sep 17 '18 at 03:33
  • @curlyBraces - What I am saying is that **at least** -128 to +127 is guaranteed. The JVM options can't reduce the cache range below that. But you are correct that it is unwise to rely on `==` ... because it is difficult to guarantee that 1) your integers are always in the range, and 2) they are never created by a direct `new Integer(...)`. (Consider deserialization, for example ....) – Stephen C Sep 17 '18 at 05:25
  • @StephenC note that the JLS makes that guaranty *only for constant expressions*. However, the boxing operation gets compiled to `Integer.valueOf` (but this compilation strategy is not specified) and the API documentation of `Integer.valueOf` makes that guaranty for any value in that range (obviously, as it can’t tell whether the argument originates from a constant expression or not). So we always get canonical `Integer` instances when boxing values in the -128…+127 range, but actually, it’s not guaranteed for results of runtime computations, unless we invoke `valueOf` manually… – Holger Sep 17 '18 at 08:23
  • Ah ... I never noticed the "constant expression" caveat. – Stephen C Sep 17 '18 at 11:38
  • What is constant expressions? – Nisrin Dhoondia Sep 17 '18 at 18:46