class Test{
public static void main(String s[]){
String s1="welcome",s2="come";
System.out.println(s1==("wel"+"come")); //prints : true
System.out.println(s1==("wel"+s2)); //prints : false
}
}
I want to know why both the println methods are giving different results. Please expla开发者_JS百科in in details.
==
always compares the references themselves.
In the first comparison, the constant string expression "wel" + "come"
is evaluated at compile-time, and so you end up with the same interned reference as for the literal used to initialize s1
.
In the second case, the concatenation is performed at execution time, creating a new string.
To compare two strings for equality of contents (rather than checking whether two references refer to the same object) use equals
:
System.out.println(s1.equals("wel" + "come"));
System.out.println(s1.equals("wel" + s2));
String s1="welcome",s2="come";
System.out.println(s1==("wel"+"come")); //prints : true
These are compile-time constants, so the compiler can inline the code to
System.out.println(s1==("welcome")); //prints : true
Here, the second part is not a compile-time constant, so the compiler can't optimize, hence a new String object is created at runtime:
System.out.println(s1==("wel"+s2)); //prints : false
Trying to test Strings for equality by comparing them with "==" operator is a bad thing to do. Strings are objects, so when using "==", you are comparing the references of two objects, not the objects themself.
Try using equals() method instead.
The ==
does object reference equality test. Use the String.equals()
method instead (to test string value equality).
s1.equals("wel" + s2);
Your second method is tested at runtime. The compiler creates new String object and compares the object reference with the new String object.
In java ==
compares objects by their reference, so it will only return true if the two variables point to the same object.
In the first case the Java compiler will realize that "wel"+"come" is a constant and use the same object (pointer to the constant pool) for s1 and for "wel"+"come". In the second case the Java compiler will not know that it is a constant and at runtime Java will create a new object when executing "wel"+s2 and the comparison will fail.
In Java one should always and with no exception use the .equals
method to compare two strings. You IDE should also give you a warning if write comparison on strings with ==
.
To compare strings you should be using the String.equals method.
It is because the compiler resolves "wel"+"come" as "welcome" before compiling the source code (optimizing it). The expression can be statically resolved before compiling, and the compiler does it.
Then, the operator == returns true in the former case because both are the the very same object "welcome" stored in the strings pool.
It is the same as if you do:
Java hasn't operator overloading, like C++ and C# have. So, this means that the ==
operator always compares references. And the strings you are comparing might be the same, but they have a different reference. What causes false
.
But why was there a true result? Well, Java creates a String Pool. All String literals will be put in the String Pool at compile time. This means that:
String literalString1 = "foo";
String literalString2 = "foo";
literalString1 == literalString2 // true
Because it are both references to the String Pool.
But as soon as you start building strings (using +
), it will create new Strings on the heap. However, the Java compiler was smart and builded the two String literals at compile time.
"wel"+"come" == "welcome"
Because of you are building them at runtime. The compiler will detect "wel" + "come"
is a String literal and will put it in the String pool. And "welcome"
is a literal as well, and will search the String pool to check if the literal is already in the String Pool. And of course it will find it and use the same reference.
The fact is that in Java , strings can be treated both as an Object or a primitive type .
as a primitive type :
String text1 = "a";
as an Object :
String text2 = new String("a");
but in java ==
always compares references not the values .
when I write this code :
text1 == text2
returns false
, now text2 + "b" == "ab"
also returns false
because it compares a runtime created object with a constant and that's what applies to your second case , in former case "wel" + "come" will be treated as "welcome" by java compiler and as a constant , it's same as the constant you defined your string variable with.
精彩评论