my dog learned polymorphism
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes when will == return true for Strings Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "when will == return true for Strings" Watch "when will == return true for Strings" New topic

when will == return true for Strings

Wilson Mui
Ranch Hand

Joined: Apr 09, 2003
Posts: 140
I know if I did something like
String s = "Test";
String b = "Test";
and then s == b, it will return true. Even though the == tests for shallow equality, the way java deals with strings that are declared as shown above, is that...this is where things get foggy, there is some pool of strings, and when you created the first String "Test," it throws that into the pool. And when you did String b = "Test" instead of recreating the pool, the java compiler just takes that same String and sets b to it. If I am wrong can somebody correct me. But I also know that if I do
String s = new String("something");
String b = new String("something");
s == b returns false. But I know there are other odd things, that I am not really familiar with. I was wondering if somebody could explain in detail all the issues with setting Strings and such. I wish I could articulate this question better, but I really don't know the terminology to do that. And quite honestly my image of this String pool, is pretty hazy too. If somebody can give me more concrete information that would be great. Thank you.
Yi Meng
Ranch Hand

Joined: May 07, 2003
Posts: 270
1. For references to Strings that are the same to the compiler, the == operator will evaluate to be true. e.g.
s1==s2, s2==s3 will both produce true in the sample code below.
2. For Strings that are evaluated only in runtime, a new string will created and thus will not == to any compilation-time evaluated string literals, although they may be "equals()".

Meng Yi
Yi Meng
Ranch Hand

Joined: May 07, 2003
Posts: 270
Another thing i noticed is the String class methods. Some, if not all, methods will return the String reference itself instead of creating a new string and return the reference to the new string, if the evaluated value is the same as the original string. e.g.

BTW, those are my understandings .....may not be necessarily true.....
Wilson Mui
Ranch Hand

Joined: Apr 09, 2003
Posts: 140
Well, then I would have to extend my question further to what it means to be a compile time string and a run-time string. I know you are saying a new String("xxxxx") is a run-time string, but can i get a more concrete definition and ruleset. Interesting theory though.
Yi Meng
Ranch Hand

Joined: May 07, 2003
Posts: 270
The string "xxxxx" will be in the string pool as compiler recognize the string literal.
And another string is created through the new operator with its value being the same as "xxxxx".
Yi Meng
Ranch Hand

Joined: May 07, 2003
Posts: 270
Creating New Strings
Earlier we promised to talk more about the subtle differences between the various
methods of creating a String. Let�s look at a couple of examples of how a String might
be created, and let�s further assume that no other String objects exist in the pool:
1 � String s = "abc"; // creates one String object and one reference
// variable
In this simple case, �abc� will go in the pool and s will refer to it.
2 � String s = new String("abc"); // creates two objects, and one
// reference variable
In this case, because we used the new keyword, Java will create a new String
object in normal (nonpool) memory, and s will refer to it. In addition, the literal
�abc� will be placed in the pool.

quote from K&B book
Francis Siu
Ranch Hand

Joined: Jan 04, 2003
Posts: 867
hi Wilson
Sorry to interrupt
The == operator will check the memory location for the compared objects and check the value for primitive type. if string case,decided by object creation or not.
Because the object creation will be reserved a unique memory location.
Hope this help

Francis Siu
Wilson Mui
Ranch Hand

Joined: Apr 09, 2003
Posts: 140
Yeah Yi, that is what I am talking about with the s.trim() == s; issues. Is there some general overviewing rule that explains that?
In addition if you do:

will return true for everything too.
Maybe Dan Chisholm can explain this...? <wink><wink>
[ May 09, 2003: Message edited by: Wilson Mui ]
Corey McGlone
Ranch Hand

Joined: Dec 20, 2001
Posts: 3271
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,

SCJP Tipline, etc.
Thomas Paul
mister krabs
Ranch Hand

Joined: May 05, 2000
Posts: 13974
If a String method returns a String and the String is identical to the original String that you were running the method on, then the two Strings will be ==.
The one exception is the intern() method. In that case the two Strings will only be == if the original string was already interned.
String a = "Test";
System.out.println(a == a.intern()); // returns true
String a = new String("Test");
System.out.println(a == a.intern()); // returns false

Associate Instructor - Hofstra University
Amazon Top 750 reviewer - Blog - Unresolved References - Book Review Blog
I agree. Here's the link:
subject: when will == return true for Strings
It's not a secret anymore!