The answer to your question is implementation dependent, and misleading. There may be anywhere from 2 to 4 "String objects" by the end of the code fragment, exactly how many will depend on the JVM, and how aggressively it intern's small strings (if at all). As has been pointed out the JDK documentation specifies String.toString() return the object, so the answer should be "2 or 3"; however, you would be very foolish to rely on this behaviour.
The reason I say this is misleading is that you are never concerned about the "number of String objects". Objects in Java are very light weight, and you are never worried about counting them.
The only qualification I would add is that while you never care about object counts, you do care about references. In the case of Strings, a nasty surprise can be the number of references to the underlying char array. String objects are flyweights that share the char array, and forgetting this can lead to severe memory leaks. A very simple way to exhaust the heap on a java program is to:
while(!multiGBFileEOF) {
String bigString = readMultiMBString();
int index = findSmallFeature(bigString);
String featureOfInterest = bigString.substring(index, index+4);
featureList.add(featureOfInterest);
}
The featureList should end up being at most a few 10KB's (~1000 list items each * (4-8 bytes for the arrayref + 12-20 bytes for the object + 8-16 bytes for the char array), ie trivial. However because some common JVM implementations share the backing array for Strings generated by substring(), this could end up trying to store the entire file in memory. The solution is to force an explicit copy of the underlying array by calling String copy = new String(featureOfInterest). Here you don't care if copy and featureOfInterest are the same object or not, as long as copy does not alias the char array behind bigString.
Good luck with your learning.
String#toStringreturnsthis