Given the following code:
StringBuffer str2 = new StringBuffer(" I don't");
StringBuffer str3 = str2.append(" get it.");
if (str2 == str3)
{
System.out.println("Equal");
}
My lecturer says , that in this case both str2
and str3
will refer to the same object
and the string "I don't get it" will be inserted into the "String pool".
I think that I get why str2
and str3
will now refer to the same object, but Why does the string "I don't get it." get in the string pool when the str3
assignment occurs?
For instance, if I do :
String s = "abcd";
then I know that now the string "abcd" will be inserted into the "String pool" IF its not already there.
I would love to get an explanation.
Why does the string "I don't get it." get in the string pool.
The "I don't get it."
string does not get into the interning pool.
One way to verify it is as follows:
StringBuffer str2 = new StringBuffer(" I don't");
StringBuffer str3 = str2.append(" get it.");
String str = new String(str3.toString());
if (str == str.intern()) {
System.out.println("It was not interned before"); // <<== This is printed
} else {
System.out.println("It was interned before");
}
If String
's content is interned, the call of intern()
will return a different ("canonical") object. As you can see, the above returns the same object, meaning that the object on which you call intern()
just became the "canonical" one (i.e. has been interned).
On the other hand, if you remove the append
, you'd get a different result:
StringBuffer str2 = new StringBuffer(" I don't");
StringBuffer str3 = str2;
String str = new String(str3.toString());
if (str == str.intern()) {
System.out.println("It was not interned before"); // <<== This is printed
} else {
System.out.println("It was interned before");
}
Now the string inside str3
is " I don't"
. Its copy is already interned, because it's the same as the string constant used in creation of the str2
.
You can run the first and the second programs side by side to see the difference for yourself.
The reason why str2 == str3
is true
has nothing to do with string pools (the slang word is "string interning"). The two are equal because StringBuffer.append
returns the object on which the append
is invoked, i.e. str2
. You do not have a second object - there's only one StringBuffer
with two references to it. The content of that StringBuffer
is the concatenation of the " I don't"
and " get it."
strings.
What you are missing is the concept of string literal.
The string in added to pool when:
and is not already in the pool.
In your example you put string literals into object of type StringBuffer
. To retrieve the string from that object you must call toString()
. To add the result to the string pool you must additionally call intern()
on that string.
To prove that we can perform a simple test.
String s1 = "This is a simple test";
String s2 = "This is a simple test";
System.out.println(s1 == s2);
StringBuffer sb1 = new StringBuffer(s1);
StringBuffer sb2 = new StringBuffer(s2);
String result1 = sb1.toString();
String result2 = sb2.toString();
System.out.println(result1 == result2);
String internedResult1 = result1.intern();
String internedResult2 = result2.intern();
System.out.println(internedResult1 == internedResult2);
The code output will be:
true
false
true
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