In this article, we’ll discuss immutable class in Java. Understanding of immutable class is very important as immutable objects play a very important role in Java. To demonstrate how important immutable classes are in Java we can take the example of String
class in Java which is designed as immutable.
Immutable objects are useful while writing concurrent programs. Since immutable object’s state can not changed, it is safe to share in multi-threaded environment. Another benefit of immutable object is in caching. Since immutable object’s state can not be changed, the cached immutable objects are always reliable and do not have dirty value.
An object is said to be immutable if it’s state can not be changed after it is constructed. The state of an object is represented by it’s member variables. If we can not change the value of its members, we can say that the object is immutable.
Following are examples of immutable classes in Java:
- java.lang.String
- The wrapper classes for the primitive types: java.lang.Integer, java.lang.Byte, java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long, java.lang.Double, java.lang.Float.
How to create immutable class in Java?
Following are the strategies to follow while creating immutable class in Java:
- Make all fields
final
andprivate
. - Do not provide “setter” methods. The immutable class should not provide any method which can modify fields. The fields can be primitive as well as reference variables.
- Do not allow subclasses to override methods. We can achieve this by declaring the class as
final
. Another approach is to make constructor of the class asprivate
and allow instantiation in factory methods. - If the class has fields which have reference to mutable objects:
- The class should not have any method which can modify the mutable object.
- The class should not share references to the mutable object. If it is required to return the reference of the mutable object, create a copy of the mutable object and return the copy.
- If any mutable object is passed to the constructor, then do not save the reference to the mutable object. Instead create a copy of the reference and save.
Example of creating immutable class in Java
Let us now use above mentioned strategies to create an immutable class Student
. Suppose we have a class Student
which is not immutable and have fields rollNo
, name
and age
.
public class Student { int rollNo; String name; Age age; }
In class Student
, age
is of type Age
which is a mutable object.
class Age { private int day; private int month; private int year; }
After applying above mentioned strategies, we get following version of Student
class.
//make class as final public final class Student { // make all fields as private and final private final int rollNo; private final String name; private final Age age; /* * If any mutable object is passed to the constructor, then don't save the * reference to the mutable object. Instead create a copy of the reference and * save */ public Student(int rollNo, String name, Age age) { this.rollNo = rollNo; this.name = name; Age copyOfAge = new Age(); copyOfAge.setDay(age.getDay()); copyOfAge.setMonth(age.getMonth()); copyOfAge.setYear(age.getYear()); this.age = copyOfAge; } // Do no provide any setter methods public int getRollNo() { return rollNo; } public String getName() { return name; } // while returning any mutable object create a copy and return copy public Age getAge() { Age copyOfAge = new Age(); copyOfAge.setDay(this.age.getDay()); copyOfAge.setMonth(this.age.getMonth()); copyOfAge.setYear(this.age.getYear()); return copyOfAge; } }