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.Integer
, java.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.
- The class must be declared as a
final
class.final
classes can not be extended. - All fields in the class must be declared as
private
andfinal
.final
fields can not be changed once initiated. - 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.
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.
You can download the full source code of this example here: Immutable Class Tutorial