string "==" in java check the reference, why this code return true? [duplicate]
Possible Duplicate:
If == compares references in Java, why does it evaluate to true with these Strings? String comparision with logi开发者_JS百科cal operator in Java
public static void main(String[] args)
{
String a = "ab";
final String bb = "b";
String b = "a" + bb;
System.out.println(a == b);
}
why it print true??
but,
public static void main(String[] args)
{
String a = "ab";
String bb = "b";
String b = "a" + bb;
System.out.println(a==b);
}
it print false.
You're seeing the result of two things working in combination:
The compiler is processing the
"a" + bb
at compile-time rather than runtime, because thebb
isfinal
and so it knows it can do that. (There are other times it knows that, too.)All strings generated by the compiler are interned. For more about interning, see this answer to another StackOverflow question about
==
in Java.
So the result is that a
and b
point to the same string instance, and so ==
returns true
.
Compiler computes string at compile time as it is final and will never change.
final String bb = "b";
String b = "a" + bb;
"a" + bb
is evaluated at compile time
Java will intern string constants (final strings) and literals (create one instance of each string in an internal pool) and thus you might get the same instance, even if it is "created" by concatenation.
And as the others already stated, compiler optimization would actually turn the concatenation into one literal ("ab").
You can never fully rely on the ==
semantics of String, that's why you should always use equals(..)
.
Edit: to clarify the above sentence:
With objects ==
always means that the references are compared and it will always return true if both references are the same. However, you can't always rely on getting the same reference of an object (like in your example where a simple final
changes behavior or in frameworks like Hibernate etc.) - that's why you generally should use equals(...)
instead.
Of course you can use ==
if you need physical equality (the very same object) instead of logical equality (the same value).
Another example where ==
would have different results, although from a locical point of view both should be true:
Integer l1 = 0;
Integer l2 = 0;
l1 == l2; //most often true, since Integer objects up to 127 are cached
Integer l1 = 1000;
Integer l2 = 1000;
l1 == l2; //most often false, since those are not cached anymore
Note that with "most often" I mean that this could change between Java versions (if not different JVMs), although that's not very likely.
The JLS specifies this in the section about String Literals:
Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. 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.
Thus, the test program consisting of the compilation unit (§7.3):
package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); System.out.print((Other.hello == hello) + " "); System.out.print((other.Other.hello == hello) + " "); System.out.print((hello == ("Hel"+"lo")) + " "); System.out.print((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; }
and the compilation unit:
package other; public class Other { static String hello = "Hello"; }
produces the output:
true true true true false true
BTW: OMM (jdk1.6.0_21, Ubuntu), the above code doesn't compile until I make other.Other.hello
public
and then it outputs:
true true true true true true
Update: nope, my fault. My IDE automatically added final
to the local variable declaration. If I remove that, I get:
true true true true false true
精彩评论