• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Using == for String Equality?

 
Fergal Crawley
Greenhorn
Posts: 18
Chrome Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It was my understanding that == should not be used for testing String equality. However, the code below works;



Why does that code work and output "Equal"?

Are there any circumstances where it is OK to use == to test for String equality?

Thanks!
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It only seems to work.

The == operator on reference types always does exactly the same thing: compares whether the two reference values are the same. That is, whether both references point to the same object, or both are null. It never compares objects' states (contents).

In this case, you seem to be assuming that you have two separate String objects. You don't. String literals are compiled into the .class file and added to a JVM-wide constant pool when the containing class is loaded, if an equal String isn't already there. So the two String references expressions, "aa" and "aa", both point to the same String object.

Are there any circumstances where it is OK to use == to test for String equality?


No. You should never rely on this behavior to shortcut to == when your semantics are about Strings' contents.
 
Carles Gasques
Ranch Hand
Posts: 199
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Are there any circumstances where it is OK to use == to test for String equality?

Never :-)

The jvm saves "aa" in the string pool then your equality check == refers to the same string in both sides and succeed.

PD: Sorry Jeff Verdegan responded while I was typing :-)


 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15441
41
Android IntelliJ IDE Java Scala Spring
 
Winston Gutkowski
Bartender
Pie
Posts: 10505
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fergal Crawley wrote:It was my understanding that == should not be used for testing String equality.

Correct; and furthermore, with very few exceptions, it should not be used to test any object's equality. Have a look at the AvoidTheEqualityOperator (←click) page for details.

And if you're interested in the "caching" Jeff referred to, you might want to check out this page.

Winston
 
Fergal Crawley
Greenhorn
Posts: 18
Chrome Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your replies. Given your explanations, I didn't expect the code below to work and output "Equal", but it does. Why is that?

 
Carles Gasques
Ranch Hand
Posts: 199
1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Take a look at the link provided by Winston Gutkowski there is well explained.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fergal Crawley wrote:Thanks for your replies. Given your explanations, I didn't expect the code below to work and output "Equal", but it does. Why is that?


This is the same question you initially asked. I explained exactly why it does that. Others also explained it, and provided links to where you can read more about it.

So what do you still not understand? What about those explanations and links leads you to believe that == will be false here?
 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15441
41
Android IntelliJ IDE Java Scala Spring
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Note that the == operator only returns true if the operands on the left and right side refer to the exact same object.

The Java compiler performs an optimization with string literals. If the same string literal, for example "aa", is used multiple times in the same program, then the compiler makes sure that only one String object is created, which is reused.

Because of this, your variables a and b refer to the same string object, and so you get true when you compare them with ==.

See: https://www.coderanch.com/how-to/java/CachedObjects
 
fred rosenberger
lowercase baba
Bartender
Posts: 12185
34
Chrome Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Try this:
 
Fergal Crawley
Greenhorn
Posts: 18
Chrome Java Netbeans IDE
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for your help Jeff. I felt it was a different question because I used variables second time round. I wasn't aware that;

Jesper de Jong wrote:...The Java compiler performs an optimization with string literals. If the same string literal, for example "aa", is used multiple times in the same program, then the compiler makes sure that only one String object is created, which is reused...


Thanks for that Jesper. Also I hadn't seen some of the earlier replies (with the links) as they were written when I was replying with my second question.

Thanks again everyone, I understand it now.
 
Jeff Verdegan
Bartender
Posts: 6109
6
Android IntelliJ IDE Java
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Fergal Crawley wrote:Thanks for your help Jeff. I felt it was a different question because I used variables second time round.


I see. I didn't even notice that as I was scrolling back and forth between the two code samples. It doesn't matter if you use member variables, local variables, the literal expressions directly, the result of method calls, or a combination of any two of those. All are expressions of type "reference to String," and == will be true for any two of them if they both refer to the same String object.



In the above, "aa", s1, s2, and getStr() are all expressions that evaluate to a reference to a String object, and because of the constant pool, they all happen to point to the same String object.

I wasn't aware that;

Jesper de Jong wrote:...The Java compiler performs an optimization with string literals. If the same string literal, for example "aa", is used multiple times in the same program, then the compiler makes sure that only one String object is created, which is reused...



Just FYI, that's basically the same thing I said in my first reply. Not trying to steal credit from Jesper since he's the one that wrote it in a way that made sense to you. :-) Just wanted to point it out, in case re-reading with the foreknowledge that it says basically the same thing helps the pieces fit into place a little better.
 
Campbell Ritchie
Sheriff
Pie
Posts: 49793
69
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It goes to show you: two people can say the same thing and one of them says it in the manner you actually understand. That happens all the time.
It may be worthwhile learning about some of the strange behaviour of Strings in an old JavaRanch Journal.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic