Chitika

Monday, April 11, 2005

Immutable classes

Here's my opinion on immutable classes, answering Bayu's comment which asks for an explanation on when and how to implement them.

Making a Java class immutable usually make the overall design of a system slightly better compared to making all Java classes mutable. Whenever possible, making such class immutable will make it easier to be implemented and maintained.

First, don't provide any mutator methods, i.e. methods which are able to modify the internal of the class. If you have to provide a mutator method, make sure that it's thread-safe.

Then, make all fields private. If you need to expose a constant value through public static final field, make sure that the internal of the constant value cannot be modified. Otherwise, you'll only open a hidden vulnerability. For example, an array or list constant value's elements may be modified without changing the reference of the array or list itself.

Sometimes, making an immutable class is a pleasure by itself. It's almost very easy to test, sometimes it needs no testing because it just cannot possibly break. Then, it's nice also to create constant values which are instances of this immutable class, just like constant values for Boolean.TRUE, Boolean.FALSE, etc.

There are many great examples of immutable class usages. Even the immutability itself can be raised to multiple levels, providing event tighter access on each level, e.g. no methods can be overridden, etc. I suggest you to read Effective Java book by Joshua Bloch. The book discusses immutability in great length.

I hope this short introduction to immutability may lure many future design to favor it whenever possible.. :D

6 comments:

  1. There are a couple other things you need to do to make a class immutable. The easier one is to make the class final.

    The other one is an extension of what you said with make sure that the internal of the constant value cannot be modified. In addition to checking this for exposed constants, you need to check this for objects returned from getters and protect them through defensive copying or another approach. If you expose a private List with a getter, wrap the list in Collections.unmodifiableList(). If the object is clonable, deep clone it, etc.

    ReplyDelete
  2. Here's something I wrote a while ago.

    http://www.javalobby.org/articles/immutable/index.jsp

    Might be interesting.

    Cheers,

    ReplyDelete
  3. Thanks Lance & Mikael,

    Your comments are valuable. The suggestions you guys made are also covered in Joshua Bloch's Effective Java book.

    It's a great article there, Mike..
    Your Immutern Pattern is very interesting.

    Many thanks again.

    ReplyDelete
  4. which class in java is an immutable class

    ReplyDelete
  5. You should also make your private members final. This not only makes them impossible to change the reference and ensures you explicitly initialise them, but that reference is guaranteed to be safely published under the Java Memory Model. This means no thread can ever see the default value for that member.

    As mentioned previously, defensively copying any references that are mutable or protecting them with an unmodifiable wrapper is a good idea too.

    ReplyDelete