This is a very common mistake, probably because of the misinformation about what the
== operator really does. This mistake is about using
== instead of
equals() to compare
When should I use them?
==is used to compare values of primitive types (
boolean, …), but it’s also used to compare object references (memory addresses).
equals()method should be used to compare contents (information) of Objects. Note that the initial implementation returns the same as
obj1 == obj2, in other words, it compares references. But this method is generally override by programmers to compare object contents, and this is the case of
Stringis an Object, not a primitive).
In conclusion, to compare
String contents we must use
equals(). But it is worth noting that
Strings content can be also compared with
== operator in some situations. Let’s see some examples:
// These two have the same value new String("test").equals("test") --> true // ... but they are not the same object new String("test") == "test" --> false // ... neither are these new String("test") == new String("test") --> false // ... but these are because literals are interned by // the compiler and thus refer to the same object "test" == "test" --> true // concatenation of string literals happens at compile time, // also resulting in the same object "test" == "te" + "st" --> true // but .substring() is invoked at runtime, generating distinct objects "test" == "!test".substring(1) --> false
Why does line 12 and 16 evaluate to
true? Because of
String interning. What happens in these cases is that the compiler interns
String literals in memory at compile time (this is done to save memory). In line 12 and 16 the
String literals that are beign compared are in the same memory location, so the comparison with
== operator returns
However, this is not recommended unless you want better performance (comparing memory addresses is a lot “cheaper” than a loop) and you are sure that the
Strings being compared are interned literals.