Learnitweb

Immutable class and how to create immutable class in Java?

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:

  1. Make all fields final and private.
  2. 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.
  3. 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 as private and allow instantiation in factory methods.
  4. 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;
	}

}