Home » Core Java » How to create Immutable class in java

About Ima Miri

Ima Miri
Ima is a Senior Software Developer in enterprise application design and development. She is experienced in high traffic websites for e-commerce, media and financial services. She is interested in new technologies and innovation area along with technical writing. Her main focus is on web architecture, web technologies, java/j2ee, Open source and mobile development for android.

How to create Immutable class in java

1. Immutable class

Immutable class is a class which the state of its instances does not change once it is constructed. Immutable objects are especially useful in concurrent applications. Since they cannot change state, they cannot be corrupted by thread interference or observed in an inconsistent state.

There are number of immutable classes in java such as java.lang.String, java.lang.Integerjava.lang.Float and java.math.BigDecimal. Lets have a look at the benefit of immutable class.

1.1. Benefits of immutable class

  • Immutable classes can simplify programming by allowing the program to cache and share the references to the immutable objects without having to defensively copy them or without having issues about their values becoming stale or corrupted.
  • Immutable class is thread safe and have no synchronization issues in multi threaded environment.
  • Immutable class doesn’t need an implementation of clone.
  • Immutable class eliminates the possibility of data becoming unreachable when used as keys in Map and Set. Immutable object must not change its state while in the collection.

2. How to implement an immutable class

Implementing an immutable class is easy. Here is some important notes about how to implement an immutable right.

  1. The class must be declared as a final class. final classes can not be extended.
  2. All fields in the class must be declared as private and final. final fields can not be changed once initiated.
  3. Do not define any methods that can change the state of the immutable object. Not only Setter methods but also any other methods which can change the state of the object.
  4. this reference must be used during constructing the immutable object. Don’t return the mutable references to the caller (Use defensive copy).

The following example displays the wrong way to implement an immutable object. The array is assigned directly in the constructor. Then, the caller could change the array after calling the constructor.

public final class ImmutableClass {

    private final String[] array;

    public ImmutableClass(String[] arr){
        this.array = arr; // wrong
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("Characters in array are: ");
        for (int i = 0; i < array.length; i++) {
            sb.append(array[i] + " ");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String[] array = {"a","b"};
        ImmutableClass immutableClass = new ImmutableClass(array) ;
        System.out.println("Before constructing " + immutableClass);
        array[1] = "c"; // change (i.e. mutate) the element
        System.out.println("After constructing " + immutableClass);
    }
}

Here is the output (the immutableClass object has been mutated.):

Before constructing Characters in array are: a b 
After constructing Characters in array are: a c 

Here is the right way to copy an object to an immutable object. The array is copied before assigning in the constructor. Then, the caller cannot change the array after calling the constructor.

public final class ImmutableClass {

    private final String[] array;

    public ImmutableClass(String[] arr){
        this.array = arr.clone(); // defensive copy
    }

    public String toString() {
        StringBuffer sb = new StringBuffer("Characters in array are: ");
        for (int i = 0; i < array.length; i++) {
            sb.append(array[i] + " ");
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String[] array = {"a","b"};
        ImmutableClass immutableClass = new ImmutableClass(array) ;
        System.out.println("Before constructing " + immutableClass);
        array[1] = "c"; // change (i.e. mutate) the element
        System.out.println("After constructing " + immutableClass);
    }
}

Here is the output (the immutableClass object has not been mutated.):

Before constructing Characters in array are: a b 
After constructing Characters in array are: a b 

Beware of using the clone() method on a collection like a Map, List, Set etc because the default behavior of an object’s clone() method automatically yields a shallow copy. Then, we need to use deep copy the mutable objects referenced by the immutable class.

Creating an Immutable class is one of common interview questions and important to know its concept.

3. Download the source code

This was a tutorial for how to create an immutable class.

Download
You can download the full source code of this example here: Immutable Class Tutorial

Do you want to know how to develop your skillset to become a Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you our best selling eBooks for FREE!

 

1. JPA Mini Book

2. JVM Troubleshooting Guide

3. JUnit Tutorial for Unit Testing

4. Java Annotations Tutorial

5. Java Interview Questions

6. Spring Interview Questions

7. Android UI Design

 

and many more ....

 

Receive Java & Developer job alerts in your Area from our partners over at ZipRecruiter

 

Want to take your Java skills to the next level?

Grab our programming books for FREE!

Here are some of the eBooks you will get:

  • Spring Interview QnA
  • Multithreading & Concurrency QnA
  • JPA Minibook
  • JVM Troubleshooting Guide
  • Advanced Java
  • Java Interview QnA
  • Java Design Patterns