The String is Immutable in Java: This is a popular interview question, and in this blog post, we’ll explore the answer together. The String class is one of the most commonly used classes in any application, so it’s essential to understand why it’s immutable.
Post On: | Why String is Immutable or Final in Java? |
Post Type: | Java Tutorials |
Published On: | www.softwaretestingo.com |
Applicable For: | Freshers & Experience |
Get Updates: | SoftwareTestingo Telegram Group |
What does Immutable mean?
Before Discussing why a string becomes immutable, let us try to understand the Immutable Meaning. An immutable object is an object whose internal state remains constant after being entirely created.
How can we achieve immutability in Java?
We can achieve immutability by following the below principles:
- Don’t provide mutator methods for any field.
- Make all fields final and private.
- Don’t allow subclasses by declaring the class final itself
- Return deep-cloned objects with copied content for all mutable fields in the class.
In Java, there are a set of immutable classes. Those classes are String Class & Wrapper classes. But in this post, we will discuss the benefit of immutability for the String class.
Why is String Immutable and Final in Java?
It is one of the most frequently asked questions about strings in Java. The String class is an essential part of Java and has many uses. The string class has many benefits because it is an immutable object.
The main benefit of making the String class immutable is cache, synchronization, security, and performance.
Requirement of String Pool
A string pool (String intern pool) is one of the vital storage places inside the Java heap memory or method area. When we create a string, if that string is already available in the string pool area, the existing string’s reference is returned instead of making a new string object in the heap memory.
Let us take an example to understand how a string pool works:
String string1 = "abcd"; String string2 = "abcd";
A new object will be created in the method area when the execution’s first statement is complete. But during the execution of the second statement, as the string is already available in the method area, JVM will return the immutable object reference instead of creating a new object.
If a string is mutable, changing the string object reference with another reference will send the wrong value for the other references.
Caching Hashcode
Since we widely use Strings in the data structure, they are also commonly used in hash implementations like HashMap, HashTable, and HashSet.
Since String is immutable, its hashcode is cached at creation time. We don’t need to calculate the Hashcode of objects multiple times, which can be helpful in terms of efficiency. Due to this, it is more efficient since it eliminates the need to calculate hashcodes every time they are used.
Using a string as a key in the map makes the processing faster than the other HashMap key objects. That’s why String is most widely used as HashMap keys.
Performance
As we saw before, the String pool exists because Strings are immutable. This enhances performance by saving heap memory and allowing faster access to hash implementations when working with Strings.
Since String is such a widely used data structure, improving its performance can significantly impact the overall performance of an application.
Synchronization
Since String is immutable, it can be safely used by multiple threads (Multithreading) simultaneously. This means that synchronization is not needed to avoid thread-safety issues. Strings are automatically thread-safe.
Security
The String class is widely used in Java applications to store sensitive information like usernames, passwords, connection URLs, network connections, etc. It’s also used extensively by JVM class loaders while loading classes.
Therefore, it is crucial to ensure the security of the String class to maintain the overall safety of the application. For example, consider this simple code snippet:
void impMethod(String userName) { // perform security checks if (!isAlphaNumeric(userName)) { throw new SecurityException(); } // do some secondary tasks initializeDatabase(); // critical task connection.executeUpdate("UPDATE Customers SET Status = 'Active' " + " WHERE UserName = '" + userName + "'"); }
When we receive the string object userName, we first perform a security check. The String is only alphanumeric, followed by some more operations.
If Strings were mutable, it would not be easy to guarantee the safety of any String we received, even after performing security checks. Because still, the source has the reference of userName and can change the string value between the security checks.
Due to multithreading, it is also possible that the String userName is also visible to other threads. So, there is a possibility that they can also change the value during the security checks.
Immutability is helpful in this case because operating with sensitive code is easier when values don’t change. Fewer interleavings of operations might affect the result if values don’t change.
String Immutability Example
To explain this, let us go step by step,
Step 1: First, we need to initialize the variable
String s = "abcd";
Now, the variable s holds the reference of the string object, as shown above. The arrow can be interpreted as a “store reference”.
Step 2: Now assign the first variable to another variable
String s2 = s;
The String variable s2 now stores the same reference as the s variable. Because it is the same string object.
Step 3: Try to concat a string “ef” to s.
s = s.concat("ef");
Now, “s” stores the reference of the newly created string object, as shown below.
Once a string is created in memory, it cannot be changed. String methods do not change the string but rather return a new One. If we need a string that can be modified, we can use StringBuffer or StringBuilder.
String Immutable Program
By this String Immutable Program, we will try to explain how the strings are immutable in nature.
package com.softwaretestingo.string; public class StringImmutableEx { public static void main(String[] args) { String var1="Software"; var1.concat("Testingo"); System.out.println("After Concat the Value of Var1: "+var1); } }
Output:
After Concat the Value of Var1: Software
Final Words:
We have learned that “Strings are immutable. Their references can be treated as normal variables and passed around between methods and threads without worrying whether the actual String object will change.”
I hope this article will help you understand the benefits of making the String immutable and final. How do you feel about the information provided in this article? You can update us by commenting in the comment section.