Reputation: 1989
Recently in a job interview I was asked this following question (for Java):
Given:
String s1 = "abc";
String s2 = "abc";
What is the return value of
(s1 == s2)
I answered with it would return false because they are two different objects and == is a memory address comparison rather than a value comparison, and that one would need to use .equals() to compare String objects. I was however told that although the .equals(0 methodology was right, the statement nonetheless returns true. I was wondering if someone could explain this to me as to why it is true but why we are still taught in school to use equals()?
Upvotes: 4
Views: 368
Reputation: 354
The reason is strings are interned in Java. String interning is a method of storing only one copy of each distinct string value which is immutable. Interning string makes some string processing tasks more efficient. The distinct values are stored in a string intern pool. (From wiki)
Upvotes: 2
Reputation: 126
Since you are not actually creating new instances of String objects for either one of these, they are sharing the same memory space. If it were
String s1 = new String("abc");
String s2 = new String("abc");
the result would be false.
Upvotes: 2
Reputation: 146
You should continue to use equals() when testing string equality. Java makes no guarantees about identity testing for strings unless they are interned. The reason the s1 == s2 in your example is because the compiler is simply optimizing 2 literal references in a scope it can predict.
Upvotes: 0
Reputation: 370112
You're right that ==
uses memory address. However when the java compiler notices that you're using the same string literal multiple times in the same program, it won't create the same string multiple times in memory. Instead both s1
and s2
in your example will point to the same memory. This is called string interning.
So that's why ==
will return true in this case. However if you read s2
from a file or user input, the string will not automatically interned. So now it no longer points to the same memory. Therefor ==
would now return false, while equals
returns true. And that's why you shouldn't use ==
.
Upvotes: 1
Reputation: 992975
String constants are interned by your JVM (this is required by the spec as per here):
All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification
This means that the compiler has already created an object representing the string "abc"
, and sets both s1
and s2
to point to the same interned object.
Upvotes: 8
Reputation: 4164
Quick and dirty answer: Java optimizes strings so if it encounters the same string twice it will reuse the same object (which is safe because String is immutable).
However, there is no guarantee.
What usually happens is that it works for a long time, and then you get a nasty bug that takes forever to figure out because someone changed the class loading context and your == no longer works.
Upvotes: 0
Reputation: 160862
java will intern both strings, since they both have the same value only one actual string instance will exist in memory - that's why ==
will return true - both references point to the same instance.
String interning is an optimization technique to minimize the number of string instances that have to be held in memory. String literals or strings that are the values of constant expressions, are interned so as to share unique instances. Think flyweight pattern.
Upvotes: 5