java string concatenation and interning
The first part of your question is simple: Java compiler treats concatenation of multiple string literals as a single string literal, i.e.
"I Love" + " Java"
and
"I Love Java"
are two identical string literals, which get properly interned.
The same interning behavior does not apply to +=
operation on strings, so b1
and b2
are actually constructed at run-time.
The second part is trickier. Recall that b1.intern()
may return b1
or some other String
object that is equal to it. When you keep a1
and a2
, you get a1
back from the call to b1.intern()
. When you comment out a1
and a2
, there is no existing copy to be returned, so b1.intern()
gives you back b1
itself.
From intern() docs
All literal strings and string-valued constant expressions are interned. String literals are defined in section 3.10.5 of the The Java™ Language Specification.
And from JLS 3.10.5
- Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals.
- Strings computed by concatenation at run time are newly created and therefore distinct.
Your string b1 not actually interned. Hence the difference.