Let's take a step back and look at just what the String literal pool is. (And before I go into great detail, let me point out that this information
is not on the exam.) Also, keep in mind throughout this discussion that .equals will check for content equality (does string1 contain the same value as string2?), while == will check only for reference equality (does string1 reference the exact same object as string2?).
A String literal in a Java application is treated just like any other constant. And, like any other constant, an entry is created in a constant table when the class is compiled. So, what does that mean?
Well, let's take the following code snippet as an example:
When this code is compiled, the compiler recognizs two distinct String literals and creates two entries in the String literal table (also known as the pool). That table would look something like this (pulled mercilessly from Rob Ross' post
here:
Remember that Strings are objects so we can't hold their values directly in the constant table like we would an int or a float. Rather, we have to hold a reference to them because these Strings, like any other object in Java, are still created on the heap. These objects are created when the class is loaded.
So, what does that mean to us when it comes to checking for equality? Let's look back at the example I posed earlier in greater detail. Notice that s1 and s4 are both Stings created from the same String literal. When the JVM encounters a String literal in this way, it basically "replaces" the literal with the reference found in the String literal table. Therefore, s1 and s4 are both assigned the same reference to a single String because they are both assigned that reference from the String literal table.
However, what about s1 and s3? Both of those Strings will have the same contents, no doubt, but will they both reference the same object? No. The reason for this is simple. The String class has a contructor which takes a String as a parameter. So, what the JVM does is replaces the String literal "A String" with the reference from the String literal table. Then, the JVM invokes the constructor of String which creates a
brand new String based on the contents of the one that was passed to it. Therefore, we have a new String object with the same contents as the Stirng literal, but it is distinct from the object references from the String literal table. Therefore, in this case, .equals will return true while == will return false.
Now, let's look at some more implications of this...
You've been asking about some of the String methods, such as trim(). If you look at the
API Spec for String, you'll see that, for the trim method, it returns:
Quote: A copy of this string with leading and trailing white space removed, or
this string if it has no leading or trailing white space.
It's important, at this time, to remember that Strings are immutable objects. That means the contents of a String
can not be changed.
Ever. Once a String is created, it will have the same contents forever.
So, how does the trim method work? Well, it looks for whitespace around the String and, if it finds some, it creates a brand new String with the same contents as the old one, but without the whitespace. If there is no whitespace, rather than creating a new String needlessly, the method simply returns the original String. So, if we have the following example:
Notice that the contents of the String referenced by s1 remain unchanged after we invoked trim on it. It still has leading and trailing whitespace. Why? Because Strings are immutable. Therefore, the trim method created a brand new String and returned it. A reference to that new String was then assigned to s3. That's why s1 and s3 do not reference the same object.
However, take a look at s2. It had no leading or trailing whitespace. Therefore, as no changes we needed, the trim method simply returned a reference to the same object it was invoked on. Therefore s2 and s4 do reference the same object and the ==
test returns true for those two objects.
Many of the String methods behave in this fashion. Be sure to check the API Spec for details.
One last note - this time about garbage collection. Remember that we have references to all String literals contained within the String literal table. So what if, in the original example, we did this?
Would the String "A String" be eligible for garbage collection? Of course not. There is still a reference to it from the String literal table. Because that reference will always be there, String literals are never eligible for garbage collection.
OK, I think I'm done rambling now. If this wasn't enough information for you, be sure to check out these threads (where I pulled a lot of this info from):
thread 1 thread 2 And remember that this info (as interesting as it is) is not on the exam.
I hope that helps,
Corey