Henry Wong wrote:
J Westland wrote:You then make the substring of long, by saying String sub = long.Substring(start, end); sub is then made by just referring to this really big String. So, we still just have one big String and one substring pointing to a part of it. This is the way Strings can save memory no need to keep making Strings for words you already have.
This is not true. Unless, the start and end are zero, and the actual end of the very large string respectively, you will get a new string back. There is no reference to the same space within the very large string.
Henry
Actually, while the terminology Jawine used might not be 100% exact, the gist of what she says is true. As a speed optimisation, the java.lang.String.substring implementation shares the underlying char buffer, and simply stores an offset and length into the substring.
Substring returns itself if it is passed 0 for beginIndex and length() for endIndex.
For any other valid values it will return a new String object, which shares the underlying char[] (which is where most of the memory is)
You can verify this yourself by reading the code at
http://www.docjar.com/html/api/java/lang/String.java.html
specifically look at substring() on line 1941, which calls the private constructor on line 644
So yes, if you create a substring from a very long string, the substring will be a new String instance, referring to the same immutable char[] as the long string, but with an offset and length specified that is taken into account in all other operations on that substring.
For all intents and purposes the memory is shared between them, and whilst the long String object might be garbage collected, the char[] (which has the bulk of the memory associated with it) will not as long as the substring refers to it!
Henry Wong wrote:
J Westland wrote:However...if you says String sub = new String(long.Substring(start, end)); you will get a totally new string that is independent of the String called long that is in the String pool. So now there will be two objects in the String pool, the really long String long, the String sub and on the heap we also have sub as an Object.
This is not true. As before, unless start and end represent the orignal string back, you will get a new string. This new string is passed to the constructor of the string, and yet another string is created. This second new string is then assigned to the sub reference. Furthermore, since no other reference now points to the response from the substring call, it is eligible for garbage collection. And finally, this operation has no affect on the string pool.
Henry
Once again, looking at the source code for the String constructor taking another string (line 163), we see that it makes a an actual copy of only that part of the original string that is needed, so Jawine was right about that. This then does allow all memory associated with the long string to be garbage collected. (as the substring will only contain a char[] large enough for that substring, an no longer a reference to original long strings char[])
You were right about the fact that it does not get added to the string literal pool.