I'm not sure of the exact order, but I think each time a literal is encountered (anything in quotes), it is checked to see if it is already in the string pool. If not, it gets created there, and if so, it is not.
Then, each time you do something like "new String()", you will create a new object. You are allowed to pass a string to a String constructor, and the constructor uses that to build the 'value' of the new string.
Note that when you do stuff like this:
I
think you actually end up with 7 objects.
on the String Pool:
"Fred"
"Rosenberger"
"Hello "
" "
dynamically built and eventually lost:
"Hello Fred"
"Hello Fred "
dynamically built and saved to a reference:
"Hello Fred Rosenberger"