Learn about String class in Java, the motivation behind making it immutable, and the idea of a String constant pool. We will see how memory is manipulated when we create String instances via String literals or String constructors. Finally, we will go through the main advantages and disadvantages caused by the immutability of the String class.
1. Immutable Strings in Java
A string is a sequence of characters. In Java, similar to other programming languages, strings are part of predefined types. Java has
java.lang.String class whose instances represent the strings.
String class is an immutable class. Immutable means a
String cannot be changed once its instance has been created.
Commonly, many sensitive information pieces (usernames, passwords, URLs, ports, databases, socket connections) are represented and passed around as strings. By having this information immutable, the code becomes secure from a wide range of security threats.
The string immutability also permits the caching of string literals, which allows applications to use a large number of string literals with a minimum impact on the heap memory and garbage collector.
In a mutable context, modifying a string literal may lead to corrupted variables.
2. What is String Constant Pool in Java?
Memory in Java is divided into three parts, i.e., Heap, Stack, and String Pool. The String Constant Pool is a special area used to store string literals.
- Please note that, before Java 7, the string pool was part of the Permanent Generation memory area.
- Starting Java 7, Strings are allocated in the Java heap area along with the other objects created by the application.
- Later, in Java 8, Permanent Generation has been completely removed.
So in the latest JVMs, the String pool is a special area in heap memory allocated for storing the String literals.
Though the String pool has been moved from Permgen space to heap memory area, all the concepts around the String creation, literals, objects and interning have not changed.
3. Difference between String Literals and String Objects
In Java, a String literal is a String created using double quotes, while String object is a String created using the
Note that string literals are created in the String pool area, and String objects are created in the heap memory area.
String strLiteral = "Hello World"; String strObj = new String("Hello World");
Suppose we want to create two strings with the same content “
howtodoinjava“. If a String with content “
howtodoinjava” already exists, the new literals will be pointing to the already existing literal. In the case of String objects, a new String object will be created in the heap every time.
Let’s see an example.
String a = "howtodoinjava"; String b = "howtodoinjava"; System.out.println(a == b); //true
In the above program, we created two string literals with the same content. After ‘a’ is created in the string pool, the next string literal ‘
b‘ points to the same object in the memory area so
'a == b' is
String a = "howtodoinjava"; String b = "howtodoinjava"; System.out.println(a == b); String c = new String("howtodoinjava"); System.out.println(a == b); //true System.out.println(b == c); //false
In the above program, we created a new String object with similar content. When we check the object reference equality, we see that
c point to separate objects. It means that when we created the String object
c, a new object was created in the memory.
4. The String.intern() API
We know that string literals are created in the String pool, and string objects are created in the heap memory area.
We can use the method String.intern() to create string literals for the string objects. When invoked on a string object, method
intern() creates an exact copy of a String object in the heap memory and stores it in the String constant pool.
String a = "howtodoinjava"; String b = "howtodoinjava"; String c = new String("howtodoinjava"); String d = c.intern();
In the above example, strings
a, b and
d will refer to the same string literal in the SCP. The string
c will continue to point to the object in the heap.
5.1. Enhanced Security
As stated earlier, the string pool allows being string immutable. Immutable objects help in making the application more secure because they may store sensitive information.
As we cannot change immutable objects, it helps make the security even more effective.
5.2. Thread Safety
Strings are perhaps the most used objects in a Java application. Imagine if strings were mutable. In that case, it would have been a nightmare to manage thread safety in an application.
Any immutable object is thread-safe by its nature. This means multiple threads can share and manipulate strings without risk of corruption and inconsistency.
6.1. String class cannot be extended
If we want to extend the String class to add more features, we cannot do it. An immutable class is declared
final to avoid extensibility.
But fortunately, we have many 3rd party libraries (Apache Commons Lang, Spring Framework, Guava) that provide excellent utility classes for almost all kinds of usages.
6.2. Sensitive data in memory for a long time
Sensitive data in strings (for example, passwords) may reside in memory (in SCP) for a longer time because SCP takes advantage of special treatment from the garbage collector. The garbage collector does not visit SCP with the same frequency (cycles) as other memory zones.
Due to this special treatment, sensitive data is kept in the SCP for a long time and can be prone to unwanted usage.
To avoid this potential drawback, it is advisable to store sensitive data (for example, passwords) in
char instead of String.
6.3. Possible OutOfMemoryError
The SCP is a small memory zone in comparison with others and can be filled pretty quickly. Storing too many string literals in the SCP will lead to
Happy Learning !!