I am trying to understand Java's String
class but I am having a hard time understanding the situation described below.
Consider the following example snippet:
String x = new String("Hey");
String y = "Hey";
If I use bool = y == x.intern();
the variable bool
will equal true
.
My question is:
When I make a declaration like this:
String b = "h";
String a = b.intern + "ey";
boolean x = a == "hey";
x
's value would be false
but when I make a = (b + "ey").intern();
x
's value will be true
.
Why won't x = true
in the second example? Is it because the declarations in the first example not alike? If yes what are the differences?
With your first example:
String y = "Hey";
Java automatically interns string literals such as this (JLS section 3.10.5):
Moreover, a string literal always refers to the same instance of class String. This is because 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.
So when you call x.intern()
, you get the interned copy of "Hey"
, so they are the same object and ==
returns true
.
But in the second example, b.intern()
is a method call that is evaluated at runtime, and Java's concatenation operator will return a new String
(not interned), which is a different object than the string literal "hey"
(interned already), so ==
returns false
(different objects).
EDIT
To clear up what happens with the string concatenation, turn to JLS Section 15.18.1:
The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).
But, b.intern() + "ey";
is not a compile-time constant expression, so the resultant String
object has not been interned, and ==
will detect that it's a different object than the interned "hey"
.
This one creates a string and stores it:
String a = b.intern() + "ey";
This one creates a string, interns it and stores the interned version:
String a = (b + "ey").intern();
All interned strings with the same content are ==
All string literals (strings supplied in the form "hey") are interned by the compiler internally.
Strings that are not interned but have the same content are only equal()
and not ==
For posterity, one more ... where the compiler optimizes out the +
resulting in "hey" and interns it just as it would the string literal "hey"
String a = "h" + "ey";
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With