Reputation: 63
public class A {
static String s1 = "I am A";
public static void main(String[] args) {
String s2 = "I am A";
System.out.println(s1 == s2);
}
}
Above program outputs "true". Both are two different identifiers/objects how the output is "true" ?
My understanding is that the JVM will create different reference for each object, if so how the output is true?
Upvotes: 5
Views: 634
Reputation: 1773
Java manages a String
literal pool. It reuses these literals when it can. Therefore the two objects are actually the same String
object and ==
returns true.
I believe this is called string interning
Upvotes: 19
Reputation: 14234
You aren't comparing the content of the strings. You are only comparing the object's references. You should use the equal method (which is a member of the String class). Either that or you can use the compareTo method (also under the same String class) to check if the return value is zero.
Please note the text above was more of a strong suggestion to the orginal state of the question as that it appeared the OP was unaware of the actual process going on behind the scenes.
The other guys suggesting internalling was right. To answer this question I didn't have enough time to go to the Java Puzzlers book. I did suspect something about setting the same reference at compile time, but I didn't know how to find a reference to that either.
Upvotes: 1
Reputation: 21902
It's because of a memory optimization performed by the compiler... namely, String
constants (ie - String
s made by the same String
literal) use the same String
object since Strings
are immutable. The ==
operator just checks that two objects are the same actual object.
If you can grab a hold of the book Java Puzzlers by Joshua Bloch and Neal Gafter, and look at puzzle 13, "Animal Farm"... he has great advice on this issue. I am going to copy some relevant text:
"You may be aware that compile-time constants of type String
are interned [JLS 15.28]. In other words any two constant expressions of type String
that designate the same character sequence are represented by identical object references... Your code should rarely, if ever, depend on the interning of string constants. Interning was designed solely to reduce the memory footprint of the virtual machine, not as a tool for programmers... When comparing object references, you should use the equals
method in preference to the ==
operator unless you need to compare object identity rather than value."
That's from the above reference I mentioned... pages 30 - 31 in my book.
Upvotes: 5
Reputation: 44706
== checks that the variables are pointing at the exact same instance of an object. The two string literals you have created point to the same place in memory and therefore the are equal. String literals are interned so that the same string literal is the same object in memory.
If you were to do
String s = new String("foo");
String t = new String("foo");
Then == would return false and s.equals(t) would return true.
Upvotes: 5
Reputation: 346377
Because the Java Language Specification says:
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.
Upvotes: 4