Java Immutable objects


Meaning of immutable object in Java or any other programing language is “object which state can not be altered/modified after it’s creation”.

immutable-java

Why immutable objects

Immutable object is widely accepted strategy to create simple, reliable code.

These object are particularly useful in multithreaded applications because these objects can not be changed so they can be corrupted and never goes in inconsistent state.

Always creation of new object to update a immutable object is overestimated by developers but if you see efficiency of immutable object then object creation overhead is offset by it’s efficiency.

A Simple multithreaded Scenario

In below example To avoid this we need to call both in one

public class SyncAB {
    private  int a;
    private  int b;

    public SyncAB(int a, int b) {
        this.a = a;
        this.b = b;
    }
    public void SetAB(int a, int b)
    {
        this.a = a;
        this.b = b;
    }
    public int getSumAB() {
        return a + b;
    }
}

Use above class object in multiple threads as given below

SyncAB obj = new SyncAB();
//....now use above object in multiple threads
//... as given below
obj.setAB(10, 20);
System.out.println(obj.getSumAB());

Suppose after execution of setAB in one thread another thread calls setAB method then in first thread result of getSumAB will be inconsistent.

To avoid this we need to call both in one synchronised block as below.

synchronized (obj) {
    obj.setAB(10, 20);
    System.out.println(obj.getSumAB());
}

Above problem will not occur in immutable objects because thread can not alter values they have to create new object instead.

How to make an object immutable

Creating immutable object is very straight forward and simple. Do not leave any thing which can lead to you object state change. Here are some strategy to make immutable objects.

  • Make all fields private and final
  • Do not provide setter method for fields
  • Mark class as final so that not one can override methods by sub classing or make constructor private and construct object via factory method.
  • Most importantly if your class has instance field(s) and if instance field member is mutable then never return it in getter and if required then always return new copy of instance field in getter methods. If instance field is immutable then no problem.
  • Do not take any mutable object reference in constructor

Immutable Example

Here i am making SyncAB immutable.

public final class SyncAB {
    private final int a;
    private final int b;

    public SyncAB(int a, int b) {
        this.a = a;
        this.b = b;
    }

    public int getSumAB() {
        return a + b;
    }
}