Reputation: 1606
When comparing two strings, I was taught that we shouldn't use the logical operator (==). We should use String.equals(String) for the comparison. However, I see that the following code complies and prints "Hello Friend
" with the latest JDK(1.6_23). I tried searching around and couldn't find any reference. From when is this happening?
public class StringComp{
public static void main(String args[]){
String s = "hello";
if(s=="hello"){
System.out.println("Hello Friend");
}else{
System.out.println("No Hello");
}
}
}
Upvotes: 4
Views: 41972
Reputation: 116306
It works in your case (and AFAIK it has been working like that in earlier JVMs as well) because s
refers to the string literal "hello"
. String references initialized with literals refer to the literal (which is a global object in the background), not a separately created new object. The term for this, as others have mentioned too, is interning. Thus s
and "hello"
in your example refer to the same physical object. Consider
String s1 = "hello";
String s2 = "hello";
String s3 = "hello";
All of these strings refer to the same physical object, thus '==' comparison between any pair of these, or between any of them and "hello"
returns true
.
However
String s4 = new String ("hello");
creates a new object, thus s4 == "hello"
yields false
.
Upvotes: 2
Reputation: 851
==
compares the object references
You can understand it by observing the output in the following code:
public class StringComp{
public static void main(String args[]){
String s = new String("hello");
if(s=="hello"){
System.out.println("Hello Friend");
}else{
System.out.println("No Hello");
}
}
}
This program would print No hello
Because in this code, the variable s
refers to new String Object which in turn refers to String literal "hello" from the String pool.
Upvotes: 0
Reputation: 114827
The magic is called interning.
Java interns String literals and so there is a high probability that it evaluates to true:
String a = "hello"; // "hello" is assigned *and* interned
String b = "hello"; // b gets a reference to the interned literal
if (a == b)
System.out.println("internd.");
String c = "hello" + Math.abs(1.0); // result String is not interned
String d = "hello" + Math.abs(1.0); // result String is not interned
System.out.println(c==d); // prints "false"
c = c.intern();
System.out.println(c==d); // prints "false"
d = d.intern();
System.out.println(c==d); // prints "true"
Upvotes: 4
Reputation: 4236
"Java Virtual Machine maintains an internal list of references for interned Strings ( pool of unique Strings) to avoid duplicate String objects in heap memory. Whenever the JVM loads String literal from class file and executes, it checks whether that String exists in the internal list or not. If it already exists in the list, then it does not create a new String and it uses reference to the existing String Object. JVM does this type of checking internally for String literal but not for String object which it creates through 'new' keyword. You can explicitly force JVM to do this type of checking for String objects which are created through 'new' keyword using String.intern() method. This forces JVM to check the internal list and use the existing String object if it is already present.
So the conclusion is, JVM maintains unique String objects for String literals internally. Programmers need not bother about String literals but they should bother about String objects that are created using 'new' keyword and they should use intern() method to avoid duplicate String objects in heap memory which in turn improves java performance. see the following section for more information."
Upvotes: 0
Reputation: 247
== compares the object references, equals() compares the values of the Strings.
In your case you are allocating two String objects both with value "hello", then comparing them with ==. The compiler may decide to optimise and use the same object reference, giving a true result like the one you got. However this is not guaranteed behaviour - it is much safer to use equals() for value comparison.
Upvotes: -1
Reputation: 64429
You shouldn't use ==
because it does something else then you think.
In this case, the "hello" is saved (Read up on string interning), so it is "coincidence" that it is the same thing as your stirng.
==
checks if two things are EXACTLY the same thing, not if they have the same content. This is a really big difference, and some accidental (though explainable) "false possitives" are no reason to use this method.
Just use equals for string comparison.
From this site an example: http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/
String a = new String ("a");
String b = new String ("a");
System.out.println (a == b);
It returns false, while the following code returns true.
String a = new String ("a");
String b = new String ("a");
System.out.println (a.equals(b));
Upvotes: 11
Reputation: 2155
The ==
operator is used to check if both are references to the same String object while .equals
compares the values.
Upvotes: 2