34

Why does the code below return false for long3 == long2 comparison even though it's literal.

public class Strings {

    public static void main(String[] args) {
        Long long1 = 256L + 256L;
        Long long2 = 512L;
        Long long3 = 512L;
        System.out.println(long3 == long2);
        System.out.println(long1.equals(long2));
    }
}
1ac0
  • 2,875
  • 3
  • 33
  • 47
Manu
  • 3,179
  • 23
  • 57
  • 69

4 Answers4

67

Long is an object, not a primitive. By using == you're comparing the reference values.

You need to do:

if(str.equals(str2))

As you do in your second comparison.

Edit: I get it ... you are thinking that other objects act like String literals. They don't*. And even then, you never want to use == with String literals either.

(*Autobox types do implement the flyweight pattern, but only for values -128 -> 127. If you made your Long equal to 50 you would indeed have two references to the same flyweight object. And again, never use == to compare them. )

Edit to add: This is specifically stated in the Java Language Specification, Section 5.1.7:

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.

Note that long is not specifically mentioned but the current Oracle and OpenJDK implementations do so (1.6 and 1.7), which is yet another reason to never use ==

Long l = 5L;
Long l2 = 5L;
System.out.println(l == l2);
l = 5000L;
l2 = 5000L;
System.out.println(l == l2);

Outputs:

true
false

Brian Roach
  • 76,169
  • 12
  • 136
  • 161
  • Hi Brian! Thanks for the answer, but can you tell me where can I find this explanation about this range (-128 -> 127)? – Renato Lochetti Feb 04 '14 at 14:43
  • 1
    @RenatoLochetti It's covered in the [Java Language Spec (JLS) section 5.1.7 - last paragraph](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7). It's an implementation of the [Flyweight pattern](http://en.wikipedia.org/wiki/Flyweight_pattern) – Brian Roach Feb 04 '14 at 16:48
  • 1
    @RenatoLochetti Edited question to expand on subject. – Brian Roach Feb 04 '14 at 17:04
3

You could also get the primitive value out of the Long object using:

str.longValue()
Mr_CRivera
  • 239
  • 2
  • 3
3

If you want to do

      str3==str2

do like this..

     str3.longValue()==str2.longValue()

This serves your purpose and much faster because you are comparing two primitive type values not objects.

madhu_karnati
  • 785
  • 1
  • 6
  • 22
1

Here Long is a Wrapper class so the below line will compare the reference not the content.

long3 == long2

its always better to compare with ** .longValue() ** like below

long3.longValue() == long2.longValue()

If we use in-build equal() method that also will do the same thing with null check.

long3.equals(long2)

Below is the internal implementation of equals() in java

public boolean equals(Object obj) {
    if (obj instanceof Long) {
        return value == ((Long)obj).longValue();
    }
    return false;
}
Banana
  • 2,435
  • 7
  • 34
  • 60
TheSprinter
  • 1,523
  • 17
  • 30