Question 1
String a1 = "I Love" + " Java";
String a2 = "I Love " + "Java";
System.out.println( a1 == a2 ); // true
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
System.out.println( b1 == b2 ); // false
In the first case, I understand that it is a concatenation of two string literals, so the result "I Love Java" will be interned, giving the result true. However, I'm not sure about the second case.
Question 2
String a1 = "I Love" + " Java"; // line 1
String a2 = "I Love " + "Java"; // line 2
String b1 = "I Love";
b1 += " Java";
String b2 = "I Love ";
b2 += "Java";
String b3 = b1.intern();
System.out.println( b1 == b3 ); // false
The above returns false, but if I comment out lines 1 and 2, it returns true. Why is that?
The method intern() creates an exact copy of a String object in the heap memory and stores it in the String constant pool. Note that, if another String with the same contents exists in the String constant pool, then a new object won't be created and the new reference will point to the other String.
The distinct values are stored in a string intern pool. The single copy of each string is called its intern and is typically looked up by a method of the string class, for example String. intern() in Java. All compile-time constant strings in Java are automatically interned using this method.
String Interning is a method of storing only one copy of each distinct String Value, which must be immutable. By applying String. intern() on a couple of strings will ensure that all strings having the same contents share the same memory.
However, when the source code compiles, the + symbol translates to chains of StringBuilder. append() calls. Due to this, mixing the StringBuilder and + method of concatenation is considered bad practice. Additionally, String concatenation using the + operator within a loop should be avoided.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With