Core Java

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

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.
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button