How to Create Immutable Class in Java

Category: Java   Tags: Java, Java Thread, Java MultiThread, Thread Synchronization, Immutable Objects

An immutable class is just like another Java class whose instances cannot be modified. All instance has own dataset and is fixed for the lifetime of that object.

To make a class immutable, follow these rules:

Declare all fields private
All fields of an immutable class should be private. This prevents accessing these fields from outside of the class. You can declare a field public or protected but that will violate the principal of immutability as it can be access and modified from outside of class.
Do not provide any methods that modify the object’s fields.
Declare all fields final.
Ensure that the class can’t be extended
The simplest way to do this is to declare the class as final. Another approach is to make the constructor private and construct instances in factory methods.
Avoid access to mutable objects
If a class has any mutable object, don't return its original reference instead make a defensive copy, store reference to it and return the reference copy.

Advantage of Immutable Objects

  • Immutable objects are by default thread-safe and they require no synchronization.
  • An immutable object will always be in exactly one state, the state in which it was created.

One disadvantage of immutable class is that they require to create a new object for each distinct value. For example if a method returns an object of type Person then it should return a new Person object every time this method is called.

Therefore you should really be careful when creating a large object. For example flipBit method of BigInteger returns a BigInteger with the designated bit flipped. All these operations are time and space consuming so be careful when creating a new object of these classes.

Here is an example of pure Java Immutable class:

JavaImmutableClassExample.java

                            package com.tutorial.javabasic;

                            import java.util.ArrayList;
                            import java.util.Collection;
                            import java.util.Collections;
                            import java.util.TreeSet;

                            class Person {

                                private final String name;
                                private final int age;
                                private final Collection<String> friends;

                                public Person(String name, int age, Collection<String> friends) {
                                    this.name = name;
                                    this.age = age;
                                    this.friends = new ArrayList(friends);
                                }

                                public String getName() {
                                    return this.name;
                                }

                                public int getAge() {
                                    return this.age;
                                }

                                public Collection<String> getFriends() {
                                    return Collections.unmodifiableCollection(this.friends);
                                }
                            }

                            class JavaImmutableClassExample {

                                public static void main(String s[]) {
                                    TreeSet friends = new TreeSet();
                                    friends.add("X");
                                    friends.add("Y");
                                    friends.add("Z");
                                    Person person = new Person("A", 20, friends);
                                    Collection<String> receivedFriends = person.getFriends();
                            //        receivedFriends.add("aaaaa");
                                    for (String friend : receivedFriends) {
                                        System.out.println(friend);
                                    }
                                }
                            }
                        

Output:

                            X
                            Y
                            Z
                          

Here inside getFriends method we are returning immutable version of friends so if you uncomment the line number 42, you will see the exception Exception in thread "main" java.lang.UnsupportedOperationException.