How to Create an Immutable Class in Java – Step-by-Step Guide

Learn about how to create an Immutable class in java and its benefits. 1 min


create-immutable-class-in-java-learn-java-for-free

Table of Contents

  1. Overview
  2. Usage of Immutable class
  3. Steps to create an Immutable class
  4. Exploring Existing Immutable classes in Java
  5. Examples with/without Mutable/Immutable class
  6. Conclusion

Let’s explore each of them.

Cover Image credits: Immutable class cover image | Image by Author Rakshit Shah

1. Overview

Immutable class means that once an object is created, we cannot change its content. In Java, all the wrapper classes (like Integer, Short, Boolean, Byte, etc.) and String class is immutable. We can create our own immutable class as well.

An object is immutable if its state cannot change after construction. Immutable objects don’t expose any way for other objects to modify their state; the object’s fields are initialized only once inside the constructor and never change again.

Always remember that,

  • Primitive data types — includes byte, short, int, long, float, double, boolean, and char.
  • Non-primitive data types — such as String, Arrays, Interfaces, and Classes.

In this article, we will explain point-to-point the typical steps to create an Immutable class with examples and their usages.

2. Usage of Immutable class

As per the current trend, In all IT industries, every software application must have to be distributed and multi-threaded. I know most of the developers are afraid of implementing Threads in their applications.

When it comes to multi-threaded applications, it always causes headaches for software engineers since they are required to protect the state of their objects from concurrent modifications of several threads at the same time. Hence, the developers normally use the Synchronized blocks whenever they modify the state of an object.

What you can do with immutable classes?

  • States are never modified
  • Every modification of a state results in a new instance, hence each thread would use a different instance and developers wouldn’t worry about concurrent modifications.

3. Steps to create an Immutable Class

  1. The class must be declared as final (Final class cannot be inherited)
  2. Data members in the class must be declared as private (It will avoid direct access)
  3. Data members in the class must be declared as final (Nobody can change the value of it on object instantiation or creation.)
  4. A parameterized constructor should initialize all the fields performing a deep copy (So that data members can’t be modified with object reference)
  5. Deep Copy of objects should be performed in the getter methods (To return a copy rather than returning the actual object reference)
  6. No setters, Don’t add any setter methods (To not have the option to change the value of the instance variable)
  7. When exposing methods that modify the state of the class, you must always return a new instance of the class.
  8. If the class holds a mutable object(s):
  • Inside the constructor, make sure to use a clone copy of the passed argument and never set your mutable field to the real instance passed through the constructor, this is to prevent the clients who pass the object from modifying it afterward.
  • Make sure to always return a clone copy of the field and never return the real object instance as mentioned in Step 7.

4. Exploring Existing Immutable classes in Java

You always heard about the well-known immutable class String. Once initialized its value cannot be modified. Operations like trim(), substring(), replace() always return a new instance and don’t affect the current instance, that’s why we usually call trim() like the following:

String str = "Rax";
str = str.trim();

Wrapper classes made for primitive datatypes compatibility are also examples of Immutable classes.

Integer, Float, Boolean, etc. — these classes don’t modify their state, however they create a new instance each time you try to modify them.

Float x = 1.5;
x += 5.5;

After calling x+= 5.5, a new instance is created holding the value: 7, and the first instance is lost.

If you know about other Immutable classes, feel free to write below in the comment section.

5. Examples with/without Mutable/Immutable class

Let’s go with simple and easy examples first.

1. Simple Immutable Class

public final class ImmutableEmployee {
  private final int id;
  private final String name;
  //Parameterized Constructor
  public ImmutableEmployee(int id, String name) {
    this.name = name;
    this.id = id;
  }
  public int getId() {
    return id;
  }
  public String getName() {
    return name;
  }
}

The above class doesn’t hold any mutable object and never exposes its fields in any way as they are final and private. These types of classes are normally used for caching purposes.

2. Passing Mutable Objects to Immutable Class

We create a mutable class called Age and add it as a field to ImmutableEmployee:

Age.java

public class Age {private int day;
    private int month;
    private int year;public int getDay() {
        return day;
    }public void setDay(int day) {
    this.day = day;
    }public int getMonth() {
    return month;
    }public void setMonth(int month) {
    this.month = month;
    }public int getYear() {
    return year;
    }public void setYear(int year) {
    this.year = year;
    }}

ImmutableEmployee.java

public final class ImmutableEmployee {private final int id;
  private final String name;
  private final Age age;public ImmutableEmployee(int id, String name, Age age) {
    this.name = name;
    this.id = id;
    this.age = age;
  }public int getId() {
    return id;
  }public String getName() {
    return name;
  }public Age getAge() {
    return age;
  }
}

If you call the main method and check whether your class ImmutableEmployee is immutable or not?

public static void main(String[] args) {Age age = new Age();
  age.setDay(1);
  age.setMonth(1);
  age.setYear(1994);
  ImmutableEmployee emp = new ImmutableEmployee(1, "Rax", age);System.out.println("Rax age year before modification = " + emp.getAge().getYear());age.setYear(1995);System.out.println("Rax age year after modification = " + emp.getAge().getYear());
}

Output:

Rax age year before modification = 1994
Rax age year after modification = 1995

Understand what just happened?

We claim that ImmutableEmployee is an immutable class The state is never modified after construction; however, in the above example, we can modify the age of Rax even after constructing Rax object. If we go back to the implementation of the ImmutableEmployee constructor, we find that age field is being assigned to the instance of the Age argument, so whenever the referenced Age is modified outside the class, the change is reflected directly on the state of Rax. Check out Pass by value OR pass by reference article to more deeply understand this concept.

How you can fix such a situation?

As said above, in step 8 to create Immutable objects, clone instance will handle everything for you.

public ImmutableEmployee(int id, String name, Age age) {
    this.name = name;
    this.id = id;
    Age cloneAge = new Age();
    cloneAge.setDay(age.getDay());
    cloneAge.setMonth(age.getMonth());
    cloneAge.setYear(age.getYear());
    this.age = cloneAge;
}

Output:

Rax age year before modification = 1994
Rax age year after modification = 1994

But, It is not the perfect Immutable class yet! Check the below example about how you can make it a perfect Immutable class.

3. Returning Mutable Objects From Immutable Class

As per step 7, when returning mutable fields from the immutable object(s), you should return a clone instance of them and not the real instance of the field.

To modify getAge() to return a clone of the object’s age:

public Age getAge() {
    Age cloneAge = new Age();
    cloneAge.setDay(this.age.getDay());
    cloneAge.setMonth(this.age.getMonth());
    cloneAge.setYear(this.age.getYear());return cloneAge;
}

It will return you perfect output for your Immutable class.

Rax age year before modification = 1994
Rax age year after modification = 1994

6. Conclusion

Advantages:

  • It gives benefit for multi-threaded environment

Disadvantages:

  • Memory Consumption is more because on each modification of them a new object is created in the memory.

Finally, an object is immutable if it can present only one state to the other objects, no matter how and when they call its methods. If so it’s thread-safe by any definition of thread-safe.

Reference:

[1] Java™: The Complete Reference Herbert Schildt

[2] Java First Head Book,

[3] DZone


I obtain an immense amount of satisfaction from helping others attain their goals and reach their potential through technology. Even if you wish to reach out and say "Hello", I sincerely appreciate all of the wonderful correspondence I receive each day from readers. You all enrich my life, and I hope I am able to do the same for you all as well.

If you find joy and value in what I do, please consider supporting my work with a donation — however much you can afford, it means and helps more than you can imagine.

You can give tips too using Buy me a coffee.

adsense


Discover more from 9Mood

Subscribe to get the latest posts sent to your email.


Like it? Share with your friends!

What's Your Reaction?

Lol Lol
1
Lol
WTF WTF
0
WTF
Cute Cute
2
Cute
Love Love
2
Love
Vomit Vomit
0
Vomit
Cry Cry
0
Cry
Wow Wow
2
Wow
Fail Fail
0
Fail
Angry Angry
0
Angry
Rakshit Shah

Legend

Hey Moodies, Kem chho ? - Majama? (Yeah, You guessed Right! I am from Gujarat, India) 25, Computer Engineer, Foodie, Gamer, Coder and may be a Traveller . > If I can’t, who else will? < You can reach out me by “Rakshitshah94” on 9MOodQuoraMediumGithubInstagramsnapchattwitter, Even you can also google it to see me. I am everywhere, But I am not God. Feel free to text me.

0 Comments

Leave a Reply

Choose A Format
Story
Formatted Text with Embeds and Visuals
List
The Classic Internet Listicles
Ranked List
Upvote or downvote to decide the best list item
Open List
Submit your own item and vote up for the best submission
Countdown
The Classic Internet Countdowns
Meme
Upload your own images to make custom memes
Poll
Voting to make decisions or determine opinions
Trivia quiz
Series of questions with right and wrong answers that intends to check knowledge
Personality quiz
Series of questions that intends to reveal something about the personality
is avocado good for breakfast? Sustainability Tips for Living Green Daily Photos Taken At Right Moment