What is the purpose of Java's String.intern()?
As you know that String
is an immutable object in Java programming language, which means once constructed can not be altered. Due to this, JVM has the ability to maintain a literal pool which is helpful to reduce the memory usage and to increase the performance. Each time when a String
literal is used JVM checks the literal pool. If the literal is already available, the same reference would be returned. If the literal is not available, a new String object will be created and added in the literal pool.
This theory is applied when you try to create a String
like a primitive or a literal/constant.
String str = "bbb";
But when you create a new String object
String str = new String("bbb");
the above mentioned rules are overridden and a new instance is created always.
But the intern
API in the String
class can be used to pick the String
reference from the literal
pool even though you create a String
using new
operator. Please check the below given example. Although the str3
is created using new
operator since we used the intern
method JVM picked up the reference from the literal
pool.
public class StringInternExample {
public static void main(final String args[]) {
final String str = "bbb";
final String str1 = "bbb";
final String str2 = new String("bbb");
final String str3 = new String("bbb").intern();
System.out.println("str == str1 : "+(str == str1));
System.out.println("str == str2 : "+(str == str2));
System.out.println("str == str3 : "+(str == str3));
}
}
Output of above code:
str == str1 : true
str == str2 : false
str == str3 : true
You can have a look: Confusion on string immutability
Source of answer: http://ourownjava.com/java/java-string-immutability-and-intern-method/
Shishir
There are essentially two ways that our String
objects can enter in to the pool:
- Using a literal in source code like
"bbb"
. - Using
intern
.
intern
is for when you have a String
that's not otherwise from the pool. For example:
String bb = "bbb".substring(1); // substring creates a new object
System.out.println(bb == "bb"); // false
System.out.println(bb.intern() == "bb"); // true
Or slightly different:
System.out.println(new String("bbb").intern() == "bbb"); // true
new String("bbb")
does create two objects...
String fromLiteral = "bbb"; // in pool
String fromNewString = new String(fromLiteral); // not in pool
...but it's more like a special case. It creates two objects because "bbb"
refers to an object:
A string literal is a reference to an instance of class
String
[...].Moreover, a string literal always refers to the same instance of class
String
.
And new String(...)
creates a copy of it.
However, there are many ways String
objects are created without using a literal, such as:
- All the
String
methods that perform some kind of mutation. (substring
,split
,replace
, etc.) - Reading a
String
from some kind of input such as aScanner
orReader
. - Concatenation when at least one operand is not a compile-time constant.
intern
lets you add them to the pool or retrieve an existing object if there was one. Under most circumstances interning String
s is unnecessary but it can be used as an optimization because:
- It lets you compare with
==
. - It can save memory because duplicates can be garbage collected.