Reputation: 733
Can anyone explain this strange behavior of String
s?
Here's my code:
String s2 = "hello";
String s4 = "hello"+"hello";
String s6 = "hello"+ s2;
System.out.println("hellohello" == s4);
System.out.println("hellohello" == s6);
System.out.println(s4);
System.out.println(s6);
The output is:
true
false
hellohello
hellohello
Upvotes: 4
Views: 329
Reputation:
String s4
is interned and reference to this string and to "hellohello" is the same.
Because of that you get true
on the line:
System.out.println("hellohello" == s4);
String s6
is not interned, it depends on a variable s2
. And references to "hellohello" and to string s6
are not equal. Because of that you get false
on the line:
System.out.println("hellohello" == s6);
But if you declare s2
as final, which makes s2
constant, you will get true
instead of false
on the line System.out.println("hellohello" == s6);
, because now compiler can intern the string s6
, as it depends on constant values, and the references to "hellohello" and to s6
will be equal to each other.
Upvotes: 2
Reputation: 198324
You need to be aware of the difference between str.equals(other)
and str == other
. The former checks if two strings have the same content. The latter checks if they are the same object. "hello" + "hello"
and "hellohello"
can be optimised to be the same string at the compilation time. "hello" + s2
will be computed at runtime, and thus will be a new object distinct from "hellohello"
, even if its contents are the same.
EDIT: I just noticed your title - together with user3580294's comments, it seems you should already know that. If so, then the only question that might remain is why is one recognised as constant and the other isn't. As some commenters suggest, making s2
final will change the behaviour, since the compiler can then trust that s2
is constant in the same way "hello"
is, and can resolve "hello" + s2
at compilation time.
Upvotes: 6
Reputation: 36304
String s2 = "hello";
String s4 = "hello" + "hello"; // both "hello"s are added and s4 is resolved to "hellohello" during compile time (and will be in String pool)
String s6 = "hello"+ s2; // s6 is resolved during runtime and will be on heap (don't apply Escape analysis here)
So,
System.out.println("hellohello" == s4); // true
System.out.println("hellohello" == s6); // false
Upvotes: 5
Reputation: 62864
"hello" + s2
works like this:
+
operator actually invokes the StringBuilder#append(String s) method"hellohello" == s6
is actually false
.More info:
Upvotes: 5