Here's a simplified version of how String literals work in
java.
In a source file, when you create a constant, the compiler does something "special" with it when you compile. This happens with any kind of constant by the way...
final int numFingers = 5; //line 1
String redColorName = "Red"; //line 2
int fingerCount = numFingers*2; //line 3
etc.
These are examples of constants. In line one, the identifier "numFingers" refers to a constant value.
When you compile this code, the compiler does something like when it converts line 3 to byte code: (again this is simplifed)
load fingerCount with value from integer constant table ID#12345 and multiply by 2.
This integer constant table is part of the .class file for the class that got compiled. Since the final variable can never change, the compiler uses the constant table as a way of storing and referencing the constant value.
Now, String literals work in a similar fashion. The ONLY difference is that a String is an object, whereas an integer is a primitive. So in the String constant table for the .class file, instead of a value like "5", a reference to the constant String object is kept. Line 2 gets compiled to something like this:
load redColorName with value from String object referenced in the String constant table ID#12345
Now, the ClassLoader that loads the .class file containing this String constant table actually creates a new String object, with the value of the literal (in this case "Red"), and stores the reference to this new String object in this String table. Each time you run the application and the .class file is loaded, the ClassLoader initializes the String constant table and makes sure that ID#12345 references a String object with the value "Red". The Value is the actual reference value, which may be interpreted loosely as a memory address, or better yet, a hash code - but it works the same way as a pointer in a language like C or C++.
Anyway, the new String is created on the Heap. ALL objects get created on the heap. But as you can see, a reference to this String object is always accessable via this String contant table. That entry NEVER gets set to null while the class is loaded. When you create your own string objects using this string literal, all you are doing is *copying* the value of the reference in the String constant table.
Ie, if you write in one of your methods.
String anotherString = "Red";
the compiler creates bytecode like I mentioned above:
load anotherString with value from String object referenced in the String constant table ID#12345
If you later set your variable to null:
anotherString = null;
All you have done is clear ONE reference to that STring object. The String object with the value "Red" is still on the heap, and still not eligible for garbage collection, because the entry in the String constant table
still contains a reference to it. And it always will while the class is loaded.
That is why String literals are NEVER eligible for garbage collection.
[ March 06, 2002: Message edited by: Rob Ross ]