Before we move on: I understand we should use .equals() to compare content. I am now just talking about if the actual references are the same for the following scenario.
Only string literals and constant expressions are guaranteed to be pooled. Since str1 + str2
is not a literal, it's up to the JVM whether or not the result will be interned. You can force it via calling intern()
as you have already found out.
This is defined in § 3.10.5 of the Java Language Specification:
A string literal is a reference to an instance of class
String
(§4.3.1, §4.3.3).Moreover, a string literal always refers to the same instance of class
String
. This is because string literals – or, more generally, strings that are the values of constant expressions (§15.28) – are “interned” so as to share unique instances, using the methodString.intern
.
Your second example, "str" + "ing"
, is a constant expression so it is guaranteed to be interned.
Also see the JavaDoc for String.intern.
This is an attempt to explain what is going on. Well-written code should probably never rely on this but always use the equals
method. Any reasonable JRE will have a check like
if (this == other)
return true;
very close to the top of String.equals
so performance wise, it shouldn't matter.