2

Possible Duplicate:
String comparison and String interning in Java

I understand how String equals() method works but was surprised by some results I had with the String == operator.

I would have expected == to compare references as it does for other objects.

However distinct String objects (with the same content) == returns true and furthermore even for a Static String object (with the same content) which is obviously not the same memory address.

I guess == has been defined the same as equals to prevent its misuse

Community
  • 1
  • 1
Peter Groarke
  • 237
  • 3
  • 10
  • 3
    Something is wrong here, because `==` definitely compares references and not objects. What do you mean by "distinct String objects?" One possibility is that you're doing something like `"Hello!" == "Hello!"`, which is actually guaranteed to work because all string literals with the same content are represented by the same `String `object. – templatetypedef Aug 31 '11 at 19:04
  • Check out this article on string interning http://javatechniques.com/blog/string-equality-and-interning/ – Bala R Aug 31 '11 at 19:05
  • == does compare references. String references are just handled in a special way by the JVM. Try these comparisons, "A String" == "A String" returns true; "A String" == new String("A String") returns false. – Nate Aug 31 '11 at 19:10
  • From [the FAQ](http://stackoverflow.com/faq#howtoask): _"When you have decided which answer is the most helpful to you, mark it as the accepted answer by clicking on the check box outline to the left of the answer."_ – Bart Kiers Aug 31 '11 at 19:11
  • Thanks Mauricio I was using voting and comments - I just realised the accept only becomes available after 15 mins - I will review – Peter Groarke Aug 31 '11 at 19:14

5 Answers5

12

No, == does just compare references. However, I suspect you've been fooled by compile-time constants being interned - so two literals end up refererring to the same string object. For example:

String x = "xyz";
String y = "xyz";
System.out.println(x == y); // Guaranteed to print true

StringBuilder builder = new StringBuilder();
String z = builder.append("x").append("yz").toString();

System.out.printn(x == z); // Will print false

From section 3.10.5 of the Java language specification:

String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Yes I believe compiler optimization of String must be the cause. As well as the above for example a Static String n = "xyz" also returns == true. – Peter Groarke Aug 31 '11 at 19:10
  • @Peter: Yes - again, you've got a string literal. It's nothing to do with the `==` operator itself behaving differently; you've just got equal references. – Jon Skeet Aug 31 '11 at 19:11
  • Also `z = "x" + "yz"; x == z; // is true` – Peter Lawrey Aug 31 '11 at 19:30
5

The reason it returns the same is because of memory optimizations (that aren't always guaranteed to occur) strings with the same content will point to the same memory area to save space. In the case of static objects they will always point to the same thing (as there is only one of it because of the static keyword). Again don't rely on the above and use Equals() instead.

One thing I should point out from Jon Skeet is that it is always guaranteed for compile time constants. But again just use equals() as it is clearer to read.

Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
4

It is due to string intern pooling

See

Community
  • 1
  • 1
jmj
  • 237,923
  • 42
  • 401
  • 438
3

The == operator does always compares references in Java and never contents. What can happen is that once you declare a string literal, this object is sent to the JVM's string pool and if you reuse the same literal the same object is going to be placed in there. A simple test for this behavior can be seen in the following code snippet:

String a = "a string";
String b = "a string";
System.out.println( a == b ); // will print true

String c = "other string";
String d = new String( "other string" );
System.out.println( c == d ); // will print false 

The second case prints false because the variable d was initialized with a directly created String object and not a literal, so it will not go to the String pool.

The string pool is not part of the java specification and trusting on it's behavior is not advised. You should always use equals to compare objects.

Maurício Linhares
  • 39,901
  • 14
  • 121
  • 158
0

I guess == has been defined the same as equals to prevent its misuse

Wrong. What is happening here is that when the compiler sees that you are using the same string in two different places it only stores it in the program's data section once. Read in a string or create it from smaller strings and then compare them.

Edit: Note that when I say "same string" above, I'm referring only to string literals, which the compiler knows at runtime.

Kevin
  • 53,822
  • 15
  • 101
  • 132