String interning

Many beginners of Java are taught never to use == operator for string equality, but to use .equals() method instead. :

if (strMyString == "ok") {
... do something
}

The reason is that when comparing primitives, == operator checks if their value is the same. But when comparing objects (like Strings), it checks if two are actually the same object. If not, comparison returns false even if the two objects have exactly the same content.

After reading the above explanation, you may be amazed that the following code returns true:

String s1 := "foobar";
String s2 := "foo" + "bar";
return (s1 == s2);

How can the == operator think that s1 and s2 are the same object when they are clearly not?

This behavior is caused by a compiler optimization called String Interning. In a nutshell, the compiler recognizes that the content of the two string literals are the same, and automatically points them to the same object thereby saving memory in contrast with having two different copies. As a side effect, the == operator returns true when comparing two interned string literals.

Since Strings are immutable (that is, their value cannot be changed after instantiated) in Java, it is not possible to accidentally modify one object while trying to modify the other.

Warning: That is not to say you can rely on this optimization and use == operator when you are comparing string literals. You can’t! It is not a safe way to write code. You should always use .equals() when comparing Strings.