public native String intern(); java doc says,
A pool of strings, initially empty, is maintained privately by the class >{@code String}. When the intern method is invoked, if the pool already >contains a string equal to this {@code String} object as determined by >the {@link #equals(Object)} method, then the string from the pool is >returned. Otherwise, this {@code String} object is added to the pool and >a reference to this {@code String} object is returned. It follows that >for any two strings {@code s} and {@code t}, {@code s.intern() == >t.intern()} is {@code true} if and only if {@code s.equals(t)} is {@code >true}.
Let's consider an example:
String temp1 = new String("abcd");
this means, a new object "abcd"
will be created in the heap memory
and its reference will be linked to temp1
.
String temp2 = new String("abcd").intern();
this means "abcd"
literal will be checked in the String Pool
. If already present, its reference will be linked to newly created temp2
. Else a new entry will be created in String Pool
and its reference will be linked to newly created temp2
.
String temp3 = "abcd";
this means "abcd"
literal will be checked in the String Pool
. If already present, its reference will be linked to newly created temp2
. Else a new entry will be created in String Pool
and its reference will be linked to newly created temp3
. This conclude that, Java automatically interns String literals.
Let's consider another example:
String s1 = "string-test";
String s2 = new String("string-test");
String s3 = new String("string-test").intern();
if ( s1 == s2 ){
System.out.println("s1 and s2 are same");
}
if ( s2 == s3 ){
System.out.println("s2 and s3 are same" );
}
if ( s1 == s3 ){
System.out.println("s1 and s3 are same" );
}
Output: s1 and s3 are same
Now when to create a String object using = " "
or using new String(" ")
?
One use case which I came across,
// imagine a multi-megabyte string here
String s = "0123456789012345678901234567890123456789";
String s2 = s.substring(0, 1);
s = null;
You'll now have a String s2 which, although it seems to be a one-character string, holds a reference to the gigantic char array created in the String s. This means the array won't be garbage collected, even though we've explicitly nulled out the String s!
The fix for this is to use String constructor like this:
String s2 = new String(s.substring(0, 1));