String s1
is a REFERENCE not an OBJECT. This means when you compare s1 == s2
you are comparing the references, not the contents of what those references point.
When you have two String literals which are the same, they are cached and the same object is used. This is done to save space. This means two string literals which have the same contents point to the same object.
When you create two new objects, they have different references so they are not equal, even if s3.equals(s4)
is true.
I suggest you look at the String.intern() method which details how Strings are pooled.
So these are all true.
s1 == s2;
s1 == s3.intern();
s3.intern() == s4.intern();
s1 == s1.intern();
s1 == s1.intern().intern().intern();
s3 != s3.intern();
In hindsight, I think Java should have had a ===
for comparing references and ==
for comparing contents i.e. calling equals as this is a common source of confusion for developers who don't understand the difference between references and objects in Java.