A couple things to remember when it comes to String objects. First of all, String objects are immutable, meaning that, once they've been created, they can't be changed. Therefore, this doesn't do what you'd expect it to:
You might have expected this to print out "str1str2", but you only get the first part of it...why? Well, like I said, String objects are immutable. Therefore, you can't change s in any way. If you take a look at the API Spec for String, you'll see this in the description of the concat method: Concatenates the specified string to the end of this string. If the length of the argument string is 0, then this String object is returned. Otherwise, a new String object is created, representing a character sequence that is the concatenation of the character sequence represented by this String object and the character sequence represented by the argument string. Examples: "cares".concat("s") returns "caress" "to".concat("get").concat("her") returns "together"
Parameters: str - the String that is concatenated to the end of this String. Returns: a string that represents the concatenation of this object's characters followed by the string argument's characters.
Notice that this method returns the string after the concatention - it creates a new string to do that, it doesn't modify a String in any way. Therefore, in order to get that bit of code to do what you expected, you'd have to modify it like this:
Another thing about Strings is use of String literals. (If you do a search in this forum, you'll find gobs of information on this, so I'll try to sum up.) When you have a line like this:
The JVM creates a new String object at runtime and inserts the value "some string" into it. However, if you have the line:
The work can be done at compile time. At that point, a reference is created in a constant table which references the String literal. This is sometimes called the String literal pool. Since these are two distinct ways of creating an object, it's only fitting that, if you were to use the == operator on them that the result would be false (the == operator only checks for reference equality) even though the result of .equals would be true. Take a look at these threads for some more good info on String literals: when will == return true for Strings Quick == question GC question One last note for you - garbage collection of Strings is not on the exam. I hope that helps, Corey
I understand about the immutability of a String object and that when you do something like: s.concat("ghijk"); it doesn't work unless you use the assignment operator on the String reference: s = s.concat("ghijk"); Corey, you're saying the difference is rutime time vs compile time for lines 2 and 3? I see now where there is the "String constant pool" you mentioned.
When the compiler encounters a String literal, it checks the pool to see if an identical String already exists. If a match is found, the ref to the new literal is directed to the existing String, and no new String literal object is created
So s2, which is defined by: String s2 = "String 1"; will be placed in the pool, since it is a String literal? [ July 07, 2003: Message edited by: leo donahue ]
Kind of... What happens is that, (and someone please correct me if I say something a little off) when you compile a class that has String literals in it, an entry is made into a "String constants" table for that class. This is really not much different than the way constant values (final variables) are stored in a table. The only difference is that, instead of having the variable name map to the constant value, the variable name maps to a constant reference to a String. So, when the class is loaded (I think), any String literals that exist in the constant table (the String literal pool) are created on the heap. So, if you have something like this:
You'll have a constant table that looks something like this:
Note that I just made some stuff up, but you can see that two String references are created in the pool, one for each String literal. Now, when you execute that code, the String literal is basically relpaced with the reference to the String found within the String literal pool. So, you can say that the value is "put into the pool," but it was really there all along. You're just assigning a value that already exists there. I hope that helps, Corey