In case of string literal :-
String s = "happ"
s = s.concat("y") //line1
In your first example:
String s = "happ";
s = s.concat("y");
By the time these statement have been executed1, String
objects have been created in the string pool to represent (respectively) the "happ"
literal, and the "y"
literal.
The execution of the second statement creates a new String
object that represents the string "happy"
. This object is NOT in the string pool.
I wanted to specifically clear this doubt on where string stores the result of concat method when operated on strings from pool vs heap.
It is created in the heap2, not the string pool. Specifically.
The ONLY method in the String
API that creates objects in the string pool is String.intern()
. (That includes constructors.)
1 - Note my careful choice of words here. If you are executing the statements for the first time, the creation of the objects in the string pool may have happened during the execution of the statements. Or it may have happened before. The exact timing is implementation specific. However, the JLS guarantees that it won't happen more than once for the same literal.
2 - Note that for a modern HotSpot JVM, the string pool is in the regular heap. It is not a separate space. The string pool is effectively just a (JVM private) data structure.
Let's just try it out.
String s = "happ";
s = s.concat("y");
System.out.println(s == "happy"); // false
s = s.intern();
System.out.println(s == "happy"); // true
String s1 = new String("Birth");
s1 = s1.concat("day");
System.out.println(s1 == "Birthday"); // false
s1 = s1.intern();
System.out.println(s1 == "Birthday"); // true
So yeah, it just doesn't matter. Only literals are being interned here, not dynamically constructed values (unless explicitly interned).