How to create immutable class in java ?

Daily Debug
3 min readApr 19, 2023

Hello..

We often hear this term in Java IMMUTABILITY so let’s discuss this in today’s article we will also be looking into how to create an immutable class in Java.

Immutability – In simple terms, immutability is a state of not changing, in java immutable objects are objects whose value cannot be changed after initialization.

In Java primitive classes float, int, long, double, all legacy classes, wrapper classes, String class etc. are immutable.

String immutability example

    String testImmutability = "String Not Immutable";
testImmutability.concat("---");
System.out.println(testImmutability);

//This will concat successfully as it will create new String object

String concat = testImmutability.concat("---");
System.out.println(concat);

//Ouput

String Not Immutable
String Not Immutable---

Now lets create custom immutable class :

Steps:

  1. Declare class as final so that no child classes will be inherited from the class
  2. To restrict the direct access to the data members, data members must declare as private and also data members need to be final so that value cannot be changed after object creation.
  3. A parameterized constructor should initialize all the fields performing a deep copy so that data members can’t be modified with an object reference.
  4. Deep Copy of objects should be performed in the getter methods to return a copy rather than returning the actual object reference.
final class ImmutableClassExample {
private final Map<String, String> dataMap;
private final String name;
private final String id;

// Making deep copy in constructor
public ImmutableClassExample(String name, String id, Map<String, String> dataMap) {
this.name = name;
this.id = id;
Map<String, String> tempMap = new HashMap<>();

for (Map.Entry<String, String> entry : dataMap.entrySet()) {
tempMap.put(entry.getKey(), entry.getValue());
}

this.dataMap = tempMap;
}
// Making deep copy in getter method
public Map<String, String> getDataMap() {
Map<String, String> tempMap = new HashMap<>();
for (Map.Entry<String, String> entry : dataMap.entrySet()) {
tempMap.put(entry.getKey(), entry.getValue());
}
return tempMap;
}

public String getName() {
return name;
}

public String getId() {
return id;
}

}

public class Test {
public static void main(String args[]) {
Map<String, String> map = new HashMap<>();
map.put("1", "One");
map.put("2", "Two");
ImmutableClassExample s = new ImmutableClassExample("ABC", "101", map);
System.out.println(s.getName());
System.out.println(s.getId());
System.out.println(s.getDataMap());

map.put("3", "third");
// Won't Change due to deep copy in constructor
System.out.println(s.getDataMap());
s.getDataMap().put("4", "fourth");
// Uncommenting Following code will cause error as we are trying to access private member
// s.id = "4";
}
}

//Uncommenting Following code will cause error as we are trying to inherit final class
/*
class CheckInheritance extends ImmutableClassExample{

public CheckInheritance(String name, String id, Map<String, String> dataMap) {
super(name, id, dataMap);
}
}
*/

Output :

ABC
101
{1=One, 2=Two}
{1=One, 2=Two}

NOTE: There should be no setter methods so that there won’t be an option to change data.

Interesting facts:

This is the method to create an immutable class in Java before Java 14.

The problem with the above solution is it is creating a lot of boilerplate code and there is scope for mistakes.

Java 14 introduced records which can be used to create such immutable read-only objects.

Records represent an immutable read-only data structure and should be used instead of creating immutable classes

One of the important aspects of records is that final fields can’t be overwritten using reflection.

To create a record of the above example all we have to do is —

record ImmutableClassExample(String name, String id, Map<String, String> dataMap) {
}

Hope this was helpful, Give a clap and drop questions in the comment section below before you leave !!!

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Daily Debug
Daily Debug

Written by Daily Debug

I am software engineer, Technical Content Writer, here to help you learn and share my insights on various tech topics.

No responses yet

Write a response