Reputation: 27899
The following segment of code interns a string.
String str1="my";
String str2="string";
String concat1=str1+str2;
concat1.intern();
System.out.println(concat1=="mystring");
The expression concat1=="mystring"
returns true
because concat1
has been interned.
If the given string mystring
is changed to string
as shown in the following snippet.
String str11="str";
String str12="ing";
String concat11=str11+str12;
concat11.intern();
System.out.println(concat11=="string");
The comparison expression concat11=="string"
returns false
. The string held by concat11
doesn't seem to be interned. What am I overlooking here?
I have tested on Java 7, update 11.
EDIT:
The whole code:
package test;
public final class Test
{
public static void main(String... args)
{
String str11="my";
String str12="string";
String concat11=str11+str12;
concat11.intern();
System.out.println(concat11=="mystring");
String str1="str";
String str2="ing";
String concat1=str1+str2;
concat1.intern();
System.out.println(concat1=="string");
}
}
Upvotes: 4
Views: 291
Reputation: 197
When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object and returning its reference.
refer this site http://java.dzone.com/articles/why-string-immutable-java
Upvotes: 2
Reputation: 124215
When you use intern()
on string that wasn't in string pool earlier this string will be placed there and every next literal will use reference to it.
But if there is already some literal in strings pool and you will try to invoke intern()
on newly created string object with same characters, it will not be placed in pool but will only return reference to string from pool. Also it will not change reference to original string on which intern
was invoked.
Since Java loads and executes some code before executing main
method there is a chance that some literals will be placed in string pool before execution of main
code.
For example String pool will contain literals such as "UTF-8"
, "charset"
, "charsetName"
, which may come from java.lang.String
, or java.nio.charset.Charset
classes. It seems that "string"
literal is one of them (I am not sure where exactly it was added to String pool).
So when you are invoking
String str11="str";
String str12="ing";
String concat11=str11+str12;
concat11.intern();
your intern
will not put "string"
from concat11
in string pool because there is one already there and other "string"
literals (like these you used in =="string"
part) will be using the one from string pool, not from concat11
.
Lets test this theory:
String s = "ABCdef";// this string will be placed in
// string pool before rest of code
String str1 = "ABC";
String str2 = "def";
String concat1 = str1 + str2;
concat1.intern();//this will only return reference to literal from pool
System.out.println(concat1 == "ABCdef");//false
// here we don't have any "ABcd" literal in pool yet
String strA = "AB";
String strB = "cd";
String concatAB = strA + strB;
concatAB.intern();//so this will put String object from concatAB to pool
System.out.println(concatAB == "ABcd");//and "ABcd" literal will use same object
output
false
true
Upvotes: 3
Reputation: 79808
If you run both of these snippets in the same program, then concat1.intern()
will add concat1
to the pool of interned strings. But concat11.intern()
won't add anything to the pool, because "string"
is already in the pool (from str2
). So your last comparison is comparing concat11
to str2
- and these are not the same object.
From the Javadoc at http://docs.oracle.com/javase/6/docs/api/index.html?java/lang/String.html
When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned.
Upvotes: 6