What is an immutable class?
An immutable class once instantiated cannot be modified. For example, String is immutable in Java.
What is meant by the statement; An immutable class cannot be modified?
Let’s try to understand. Once a java.lang.String
object is created, it cannot be modified. ‘It‘ here means the state of a String object. Now if we recall the basics of object-oriented development, the state of an object is determined by the values held by its member variables. Whereas, the behavior of an object is determined by its member methods. Therefore, the statement “An immutable class cannot be modified” means that the value of the member variables of an object of an immutable class cannot be modified.
Ok, but why can’t an object of java.lang.String be modified?
Well, if we look inside the java.lang.String
class, it has a private final char value[];
member variable. This is where the String
class holds the content. So if we create an instance,
String name = new String("James");
the value “James” will be stored as a character array in the private member variable value[]
. Now the important point to note here is that value[]
is a final
member variable. And, a final
member variable once assigned a value, either via an initializer or an assignment statement, cannot be modified.
So what happens if we try to change a java.lang.String object?
If a String
object is modified, it results in the creation of a new String
object, but the original String
object is never modified. Following program explains immutability in java.lang.String
.
package com.planetofbits.string.immutability.demo; import java.io.PrintStream; import java.util.Arrays; public class StringImmutabilityDemo { public static void main(String[] args) { PrintStream out = System.out; /** * *** java.lang.String class is immutable by default *** */ // Create a String object and assign a reference to it String str1 = "Earth"; // Assign the first reference to another String type reference String str2 = str1; // Now, str2 also points to the String "Earth" // Let's print the value of both references out.println("BEFORE:"); out.println("str1 -> " + str1); out.println("str2 -> " + str2); // Add more to the first string str1 = str1.concat(" and Moon"); // Let's print the value of both references out.println("AFTER:"); out.println("str1 -> " + str1); out.println("str2 -> " + str2); out.println("-------------------------------"); /** * *** However, primitive types are mutable *** */ char[] name1 = { 'J', 'a', 'm', 'e', 's' }; char[] name2 = name1; out.println("BEFORE:"); out.println("name1 -> " + Arrays.toString(name1)); out.println("name2 -> " + Arrays.toString(name2)); // Change name1 name1[3] = 'i'; name1[4] = 'e'; out.println("AFTER:"); out.println("name1 -> " + Arrays.toString(name1)); out.println("name2 -> " + Arrays.toString(name2)); } }
Following is the output of the above code
The output of the program clearly shows that when str1
is modified, it does not cause a change in the value of str2
although both of them point to the same String initially. This is because changing str1
creates a new String object and str1
references that new String object after modification. It stops referencing the original String. But str2
still keeps pointing to the original String object. This is visually explained in the diagrams below.
The primitive data types however, are not immutable. A change in the values at 3rd and 4th index of character array name1
causes a similar change in name2
because both of them keep pointing to the same character array even after one of them is modified.
Thanks! Yes, I’ll definitely enhance this topic with your suggestions.
Great example, it would be great if you can enhance the blog to explain immutability e.g.
• How to make immutable objects?
• Defensive copying
Making class as immutable is highly recommended, these objects are thread safe and protect us from several design issues in application. Effective Java by Joshua Bloch say’s we should always make class immutable if it is not possible to make it immutable we should limit its mutability as much as possible.
Great example to learn about the string. This one is very helpful to explain String pool also