Java – How to construct an immutable class ?

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

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

Steps Descriptions
Make or declare class as finalSo that, it can’t be inherited
Declare all instance member variable as privateSo that, it isn’t accessible outside class
Also declare all instance member variable as finalThis 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 construct with initial/final valuesTo 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

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

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

3. 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

3.1 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:

Happy Coding !!
Happy Learning !!

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