Creating an Immutable Class in Java

An immutable class is one whose state can not be changed once created. There are certain guidelines to create a class immutable in Java.

In this post, we will revisit these guidelines.

Table of Contents

1. Rules to create immutable classes
2. Java immutable class example
3. Benefits of making a class immutable
5. Summary

1. Rules to create immutable classes

Java documentation itself has some guidelines identified to write immutable classes in this link. We will understand what these guidelines mean actually by creating an immutable class with mutable object with Date field.

  1. Don’t provide “setter” methods — methods that modify fields or objects referred to by fields.

    This principle says that for all mutable properties in your class, do not provide setter methods. Setter methods are meant to change the state of an object and this is what we want to prevent here.

  2. Make all fields final and private

    This is another way to increase immutability. Fields declared private will not be accessible outside the class and making them final will ensure the even accidentally you can not change them.

  3. Don’t allow subclasses to override methods

    The simplest way to do this is to declare the class as final. Final classes in java can not be extended.

  4. Special attention when having mutable instance variables

    Always remember that your instance variables will be either mutable or immutable. Identify them and return new objects with copied content for all mutable objects. Immutable variables can be returned safely without extra effort.

    A more sophisticated approach is to make the constructor private and construct instances in factory methods.

2. Java immutable class example

Lets apply all above rules for immutable classes and make a concrete class implementation for immutable class in Java.


import java.util.Date;

/**
* Always remember that your instance variables will be either mutable or immutable.
* Identify them and return new objects with copied content for all mutable objects.
* Immutable variables can be returned safely without extra effort.
* */
public final class ImmutableClass
{

	/**
	* Integer class is immutable as it does not provide any setter to change its content
	* */
	private final Integer immutableField1;

	/**
	* String class is immutable as it also does not provide setter to change its content
	* */
	private final String immutableField2;

	/**
	* Date class is mutable as it provide setters to change various date/time parts
	* */
	private final Date mutableField;

	//Default private constructor will ensure no unplanned construction of class
	private ImmutableClass(Integer fld1, String fld2, Date date)
	{
		this.immutableField1 = fld1;
		this.immutableField2 = fld2;
		this.mutableField = new Date(date.getTime());
	}

	//Factory method to store object creation logic in single place
	public static ImmutableClass createNewInstance(Integer fld1, String fld2, Date date)
	{
		return new ImmutableClass(fld1, fld2, date);
	}

	//Provide no setter methods

	/**
	* Integer class is immutable so we can return the instance variable as it is
	* */
	public Integer getImmutableField1() {
		return immutableField1;
	}

	/**
	* String class is also immutable so we can return the instance variable as it is
	* */
	public String getImmutableField2() {
		return immutableField2;
	}

	/**
	* Date class is mutable so we need a little care here.
	* We should not return the reference of original instance variable.
	* Instead a new Date object, with content copied to it, should be returned.
	* */
	public Date getMutableField() {
		return new Date(mutableField.getTime());
	}

	@Override
	public String toString() {
		return immutableField1 +" - "+ immutableField2 +" - "+ mutableField;
	}
}

Now its time to test our class:


class TestMain
{
	public static void main(String[] args)
	{
		ImmutableClass im = ImmutableClass.createNewInstance(100,"test", new Date());
		System.out.println(im);
		tryModification(im.getImmutableField1(),im.getImmutableField2(),im.getMutableField());
		System.out.println(im);
	}

	private static void tryModification(Integer immutableField1, String immutableField2, Date mutableField)
	{
		immutableField1 = 10000;
		immutableField2 = "test changed";
		mutableField.setDate(10);
	}
}

Program output:

100 - test - Tue Oct 30 21:34:08 IST 2012
100 - test - Tue Oct 30 21:34:08 IST 2012

As it can be seen that even changing the instance variables using their references does not change their value, so the class is immutable.

Immutable classes in JDK

Apart from your written classes, JDK itself has lots of immutable classes. Given is such a list of immutable classes in Java.

  1. String
  2. Wrapper classes such as Integer, Long, Double etc.
  3. Immutable collection classes such as Collections.singletonMap() etc.
  4. java.lang.StackTraceElement
  5. Java enums (ideally they should be)
  6. java.util.Locale
  7. java.util.UUID

3. Benefits of making a class immutable

Lets first identify advantages of immutable class. In Java, immutable classes are:

  1. are simple to construct, test, and use
  2. are automatically thread-safe and have no synchronization issues
  3. do not need a copy constructor
  4. do not need an implementation of clone
  5. allow hashCode() to use lazy initialization, and to cache its return value
  6. do not need to be copied defensively when used as a field
  7. make good Map keys and Set elements (these objects must not change state while in the collection)
  8. have their class invariant established once upon construction, and it never needs to be checked again
  9. always have “failure atomicity” (a term used by Joshua Bloch) : if an immutable object throws an exception, it’s never left in an undesirable or indeterminate state

4. Summary

In this tutorial, we learned to create immutable java class with mutable objects as well as immutable fields as well. We also saw the benefits which immutable classes bring in an application.

As a design best practice, always aim to make your application Java classes to be immutable. In this way, you can always worry less about concurrency related defects in your program.

How to write an immutable class? This could be an interview question as well.

Happy Learning!!

Read More:

Why string class is immutable in Java?

Leave a Reply

108 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions, and frequently asked interview questions.

Our Blogs

REST API Tutorial