Saturday, February 27, 2010

Creating Immutable Objects in Java

Immutable Objects are those objects, who cannot change their STATE once they are created. Most common examples of such objects are String, Integer, Double etc.. (other Wrapper classes). By State, we mean the values assigned to the instance variables of the object in question.

Immutable Classes are one of the most robust classes that you can ever build and the reasons that we love them are:

  • They are Thread-safe, hence no need to synchronize them for concurrent access.
  • They are Easy to construct, test and use
  • They Serve as good Map and Set keys
  • If such an object throws an exception, it is never left in undesirable or inconsistent state.

Strategy to Construct Immutable Objects

If we follow the following steps, we can easily create Immutable objects or convert an existing Mutable class into Immutable:

  • Since we have to restrict our object to change its state once they are created, we must not provide any setter methods.
  • If a object has references to other mutable objects, then do not provide getter methods that simply return a reference to the mutable object. Rather, create a new object containing the copy of the mutable object.
  • Don't allow any subclass to override methods of the given class. This can be done by making the class as final. Another way is to make the constructor as private and provide factory methods to construct the object.
  • Make all the fields private and final. This way only your class has  the control how these fields are to be manipulated.

Person1

  • Also, do not provide any other methods that modify the object. In case you have to, then do not modify the existing object, rather create a copy of the original object, modify it and return the modified object.
  • Construct the whole object in one go, initialize the whole object (assign values to all the instance variables) while creating the object.

Person2

One may argue that immutable objects calls for creation of unnecessary objects every now and then, for example if we do

Person3

then a new String is created and the original string is not modified. For argument sake, we have 3 Strings created here. viz. “Agraj”, “ Mangal” and “Agraj Mangal”.

But this so-called shortcoming is taken care of by the Garbage Collector in Java, which marks any dead object for Garbage Collection (any object which has no active reference to it in any thread of execution)