Why String Class has been made immutable in Java?

A String object is immutable that means there is no way to change its contents (the state of the object) once it is created. There are no methods provided that allow you to manipulate the contents of the string once it is created. Methods provided with the string class that operate on a string always return a new string rather than returning an updated copy of the old one. Let us see why the string objects has been made as immutable and what are the merits and de-merits of having String class is immutable. This tutorial also discusss the best practises of using string concatenation with Java.

The primary reason to have string object made immutable is that

1. Several security features of the Java programming language depend upon String objects (specified in  JLS)

2. For conserving memory by reusing the exisiting String object

Merits & Demerits : String class has been made immutable in java which has some positives and Negatives which are as follows.

1. Helps for Java Security :

Many Java classes accepts String as arguments , for example: To create instance of a file , File class accepts path and file name as String , to load class when JVM needs , methods of Class Loader accepts class name as String , to create a network connection, Socket class accepts host name as string , etc ….

If String is mutable ,there may be chance for security threat . Consider the following scenerio. When the JVM needs access to a particular class, it is the duty of the class loader to load the specified class . Here the class name is passed as String . Once the class name is passed , the class loader goes through various steps like consulting security manager,consulting internal class loader , etc before actually loading the class. If string is not final , malicious code or other thread will be able to change the class name , that leads to load a wrong class , which may be big security flaw in java. But, it will not happen , because java.lang.String class is final and it has a private char array variable to represent the string , which is very important to several aspects of Java security.

Threat for Security : There is a chance of security threat , if string is immutable . It is always possible to store sensitive data such as passwords in a String . As string is immutable , there is no method to modify / clear the contents of the string after usage . JVM may retain strings long even though they are no longer needed. This makes String objects not suitable to store sensitive data . char array may be used for that .

2. Saving Memory : Whenever we create a new String literal, the JVM puts it into a special part of memory called the String Pool . If the String Pool already contains a String with the same value, the JVM doesn’t create a duplicate, instead it simply make the reference variable to point to the existing entry. That means strings can be reused by any code running in the same JVM that has the same string literal. This saves the memory . But think String pool without making String object immutable. Suppose for example, 100 reference variable in various code points to a same String object.

String a1=”XYZ”;

String a2=”XYZ”;

………

………

String a100=”XYZ”; Only one string object “XYZ” is created in String pool. Now what will happen, if Strings are mutable . If we change String value “XYZ” to “ZYX”, it reflects in all references variables which leads to a big mistake. But that is not happening as String is immutable.

Wastage of Memory : String pool and making of string immutable saves memory but at the same time , you have to be careful when using String concatenation using the “+” operator which creates many temporary objects makes poor performance . For example :

String str = “0”;

for (int i=1; i <=9; i++) {

str = str + i;

}

We need the output of “0123456789” , But the above code creates nine unnecessary temporary objects 01 , 012 , 0123 , 01234 ,012345, …012345678 which waste the memory.

3. As String is immutable ( state of the string object cannot be changed) , we are free to share string objects across all threads without synchronization which reduces concurrency errors.

4. The immutable objects such as Strings can be safely used as keys in HashMap / HashTable . If you are able to change the value of the Key, after it is inserted in the Map , the hash value of the Key is changed which is used to decide the location of the Key in the array and looking up the values in the map becomes unpredictable.

5. Hashcode of same immutable objects are always same. Immutable object’s hash code can be cached to reduce time taken to recalculate the hash code every time when it is called. As string is immutable ,Java caches the hash code of string object . The following code is used to calculate the hash code of a string and caches. hash variable is used to cache the hash code . If the hash is 0 , then the hash code (h) of the string is calculated and returned . The hash code value is assigned to hash variable so that the next call to hash code method of the same string does not need to recalculate the hash code and just returns the hash value which is already cached.

 From <a href="http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/8-b132/java/lang/String.java#String.hashCode%28%29">Java Source</a> :
 /** Cache the hash code for the string */
private int hash = 0;
//to calculate the hashcode of a string 
public int hashCode() {
 int h = hash;   
 if (h == 0) {
     int off = offset;
     char val[] = value;
     int len = count;
            for (int i = 0; i &lt; len; i++) {
                h = 31*h + val[off++];
            }
            hash = h;
        }
        return h; // returns the hashcode
    }

do’s and don’ts

Don’t use : String s = new String(“Dont use”); if it is used in a loop, multiple instance are created

Use : String s=”Use”. Only Single instance is created even if it is used within the loop.

Don’t use String’s concatenation (+) as given below

Use StringBuffer for String concatenation which is efficient and increases performance

Don’t use == for string content equality

Use equals() method to check contents are equal or not.

String n=”Test”;

String m=new String(“Test”); // not recommended

System.out.println(n==m); // returns false

System.out.println(n.equals(m)); // returns true

You may also like

Leave a Reply

Be the First to Comment!