Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Difference between == and .equals in Java.

I know this has been covered but I've seen inconsistent arguments here on SO.

So if I have:

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + a == b);

I get FALSE.

As I understand it, it's because a and b are two different references to the same object (apple2e).

So I would have something like:

a (reference_id 123) ------
                           ---------  "apple2e"
b (reference_id 456) ------

Now, if I just want to compare the contents of the two strings, I would use a.equals(b)

Does that mean that the JVM is simply returning if the two references are pointing to the same object? So it's not really doing a character-by-character comparison?

Thanks

EDIT

Hold the phones. Thanks delnan for pointing out the + precedence!!!

When I change it to:

System.out.println(a == b);

I indeed get true.

This makes more sense.

EDIT 2

I can't believe I didn't catch that. lol

I was doing:

"a==b? " + a == b

Which translates to

"a==b? apple2e" == "apple2e"

No wonder it was false!!

like image 615
cbmeeks Avatar asked Nov 29 '22 03:11

cbmeeks


1 Answers

As I understand it, it's because a and b are two different references to the same object (apple2e).

Because of string interning, and only because of string interning a and b are different references to the same String object.


Unfortunately, your code does not do what you think it does. Try this:

String a = "apple2e";
String b = "apple2e";

System.out.println("a==b? " + a == b);    // "false"
System.out.println("a==b? " + (a == b));  // "a==b? true"

Java automatically interns all string literals. That is why the second sysout prints what it does. The first sysout prints only "false" because string concatenation (+) has higher precedence than ==, so it's equivalent to this:

System.out.println("a==b? apple2e" == "apple2e");

I don't think that's what you meant to test!

This, on the other hand, will give you two separate String instances:

String a = new String("apple2e");
String b = new String("apple2e");

System.out.println("a==b? " + (a == b));  // "a==b? false"

Which would schematically look like

a (reference_id 123) ---------------  "apple2e"

b (reference_id 456) ---------------  "apple2e"

and can be reduced to the original situation using String#intern():

String a = new String("apple2e").intern();
String b = new String("apple2e").intern();

System.out.println("a==b? " + (a == b));  // "a==b? true"

e.g.

a (reference_id 123) ------+
                           +---------  "apple2e"
b (reference_id 456) ------+
like image 178
Matt Ball Avatar answered Dec 10 '22 03:12

Matt Ball