How to construct an immutable class in Java

In this article, we will discuss how to construct or create an immutable class step-by-step

This is one of the favorite interview questions for fresher and experienced Java developers

But interviewer interested to know how deep your understanding about Immutability concept in Java

 

How to construct an immutable class in Java

Generally, one starts with below key points about Immutability in Java,

Steps  Descriptions
Make or declare class as final So that, it can’t be inherited
Declare all instance member variable as private So that, it isn’t accessible outside class
Also declare all instance member variable as final This is the additional check in multi-threaded environment and makes variables as CONSTANT
Don’t provide any setter methods (only getter method to access the values of reference variables) As providing setter methods leads to state change

Note: even if setter methods are provided, compiler throws exception during compilation; because of final modifier present in every member variables

Provide Constructor To set values of member variables (only once during Object construction)

Note: this values remain CONSTANT and doesn’t change over period of time

Hint: while constructing Immutable class in Eclipse IDE, it doesn’t allow providing setter methods and raises error saying “The final field <classname.fieldname> cannot be assigned

 

Example 1: Covering 3 key points discussed for immutable class

Student.java

package in.bench.resources.immutable.java.object;

public final class Student {

	// member variables
	final private Integer studentId;
	final private String studentName;

	// constructor
	public Student(Integer studentId, String studentName) {
		super();
		this.studentId = studentId;
		this.studentName = studentName;
	}

	// getters for member variables
	public Integer getStudentId() {
		return studentId;
	}

	public String getStudentName() {
		return studentName;
	}
}

 

Tricky Scenario: But there is one tricky scenario in the above discussed points, let us discuss this scenario in detail with example & explanation

 

What if above constructed immutable class contains mutable reference or mutable instance variable like Date or List?

Answer is to return copy of original object via getter method

 

Let’s see improved version of immutable class which has mutable reference

Example 2: Immutable class consisting mutable reference

Employee.java

package in.bench.resources.immutable.java.object;

import java.util.Date;

public final class Employee {

	// member variables
	final private Integer employeeId;
	final private String employeeName;

	// mutable reference variable
	final private Date dateOfJoining;

	// constructor
	public Employee(Integer employeeId, String employeeName, Date dateOfJoining) {
		this.employeeId = employeeId;
		this.employeeName = employeeName;
		this.dateOfJoining = dateOfJoining;
	}

	// getters for member variables
	public Integer getEmployeeId() {
		return employeeId;
	}

	public String getEmployeeName() {
		return employeeName;
	}

	// return copied date
	public Date getDateOfJoining() {
		return new Date(dateOfJoining.getTime());
	}

	// override toString() method to print values to console
	@Override
	public String toString() {
		return "Employee [employeeId=" + employeeId 
				+ ", employeeName=" + employeeName 
				+ ", dateOfJoining=" + dateOfJoining + "]";
	}
}

Explanation:

  • Since, all member variables (both mutable & immutable) are marked with private & final modifier, there is no opportunity to change values from outside of class (including in a multi-threaded environment)
  • Providing constructor helps to construct Object, thus initializing values of all fields of the immutable class (this is one-time activity, as generally initialized values can’t changed due to the presence of final modifier in every fields)
  • Again providing getter methods helps to return CONSTANT values for everyone accessing immutable fields from outside of class
  • Now for special mutable reference variable case, we are creating new Date object and thus copying original value into the arguments
  • Thus, in this way we can make immutable class

 

What are pre-defined immutable classes in Java (or in-built Java classes) ?

Answer: String and all wrapper classes like

  • Boolean
  • Character
  • Byte
  • Short
  • Integer
  • Long
  • Float
  • Double

 

Advantages of immutable class:

The main advantage of making a immutable class is that

  • its thread-safe in a multi-threaded environment and
  • typically programmer doesn’t need to take care of synchronization

 

Hope, you found this article very helpful. If you any suggestion or want to contribute any other way or tricky situation you faced during Interview hours, then share with us. We will include that code here.

 

References:

https://docs.oracle.com/javase/tutorial/essential/concurrency/imstrat.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
https://docs.oracle.com/javase/tutorial/java/data/strings.html
https://docs.oracle.com/javase/tutorial/java/IandI/final.html
http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5-110

 

Happy Coding !!
Happy Learning !!

Oracle OSB-SOA-BPEL Interview Question and Answer - Part 1
Singleton design pattern - restricting all 4 ways of Object creation in Java
  • sachin shukla

    Gr8 explanation Keep up the gud work!!