Skip to main content

(Not So) Stupid Questions: (2) String Equality

April 7, 2004


(Not So) Stupid Questions:

String Equality





Editor's note: Sometimes, the most interesting discussions begin when someone says, "This may be a stupid question, but ...". If the person asking the question has taken the time to think about the problem before asking, the question is often not stupid at all. The uncertainty points out an ambiguity in the specs, holes in the docs, or a search for how more experienced programmers might address a particular problem. From time to time, we will print one of the "(Not So) Stupid Questions" we receive and invite our readers to answer the question in the feedback section. This one began in a different form as a suggestion from Vladimir V. Ostromensky. He sent us some sample code somewhat like the code we present below with a question about String equality. We have adapted and extended his initial question.

Remember that new people are joining the Java community all the time and may be looking for help from those with more experience. Also, those who began with Java as their first language can benefit from those coming to the community with experience in other languages. As always, answer the questions with kindness. You are also welcome to submit your questions to .

This may be a stupid question, but... "Some side-effects of String equality don't make sense"

One of our readers submitted the following code, which had us scrambling for our javadocs and a copy of the Java Language Specification. Compile the following:

public class StringTester {

public static void main(String args[]){
    String aString = "myValue";
    String bString = "myValue";
    String cString = "";
    if (args.length ==1 ) cString = args[0];
   
    boolean test1 = aString.equals(bString);
    System.out.println("a.equals(b): " +
        aString + ".equals("+bString+") is " + test1);
     
    boolean test2 = aString == bString;
    System.out.println("a==b: " +
        aString + " == " + bString+" is " + test2);
   
    boolean test3 = aString.equals(cString);
    System.out.println("a.equals(c): " +
        aString + ".equals("+cString+") is " + test3);
   
    boolean test4 = aString == cString;
    System.out.println("a==c: " +
        aString + " == " + cString+" is " + test4);
}
}

When run with myValue as the command-line argument, this produces the following output:

a.equals(b): myValue.equals(myValue) is true
a==b: myValue == myValue is true
a.equals(c): myValue.equals(myValue) is true
a==c: myValue == myValue is false

So, the two constants, aString and bString are not only equivalent, they're the same object, yet cString is equivalent but is a different object. My question is:

What's the deal with String equality?

First thoughts:

We can see that aString and bString are the same object. Doesn't the spec tell us that

  1. All Strings are immutable.
  2. All Strings are held in a "String pool", with one unique instance of each string of characters.

In other words, doesn't this explain the object equality of aString and bString; they're the same run of characters, so there's one object in the String pool pointed to by both aString and bString.

The fact that aString and cString are equivalent but are different objects seems to indicate that point #2 is not entirely true. Since cString consists of the characters myValue, just like aString and bString, it should point to the same member of the String pool, and thus have pointer equality, right?

So, aString, bString, and cString have identical values and yet are not equal. It seems that cString is not working with the String pool as it is a unique object with the same value as the other two.

Strings are unusual in Java because often developers treat them as primitives when they are really objects. Part of this confusion comes up for new developers because a String can be instantiated without using new as String a = "hello". But we have more of this possible confusion coming with autoboxing and autounboxing. Are there going to be problems with equals in the future that arise from boxing and unboxing?

This brings me to three questions:

1. What is going on with String equality?

And the two follow-on questions:

2. Why might this be the desired behavior? and

3. Are we going to have more problems with equals starting in J2SE 1.5 that result from the autoboxing and autounboxing?

(Not So) Stupid Questions is where we feature the questions you want to ask but aren't sure how.

Related Topics >> Programming   |