Your understanding is correct in case of pool where all the literals goes into strings pool.
And the confusion arises when you do the concatenation. Here is the two points to note.
1) If the String resolves at compile time, yes it syncs with String pool and uses the same literals. For ex
String str7 = "Helllo";
String str8 = "He" + "llo";
Note that both are plain literals. Hence no runtime conversions etc.
2) If the String resolves at run time, it resolves to a a new string at runtime and differs with any other other string unless you use .equals method to compare its content.
String str7 = "Hel" + s;
String str8 = "He" + "llo";
System.out.println("str7 == str8 is " + (str7 == str8)); //false
In this case concat strings with (+) operator, JVM returns new StringBuilder(string...).toString()
cause one is a plain literal and other is a variable.
Look at the Java language specification
If only one operand expression is of type String, then string conversion (§5.1.11) is performed on the other operand to produce a string at run time.
Questions from comment :
does it mean that in case the string is produced as the product of concatenation of literals then the result is always the same string in the pool?
Yes it is.Remember that concatenation you mean by compile time resolved expression (aka constant expression) and not Runtime.
And when we concatenate string literal with string object then the resulting string is always a new string object built by means of StringBuilder under the hood?
Yes a new String been returned. Attached JVM link confirms you that.