How to make Java classes immutable

Immutable classes have been a hot topic lately. The rise of functional languages who operate mostly on immutable data and the advantage of immutable data when using multiple threads (correct immutable classes are thread safe) have also created a new interest in immutable data in Java.
While some languages like Scala encourage (but do not enforce) a programming style using immutable classes, in the Java world this is less common but it can be done nonetheless. In face, many classes in the JDK are immutable, for example classes like Long, Integer, Double, etc are all immutable. Also BigInteger or BigDecimal and of course the String class are immutable.

Immutable classes are also more secure. For example an attacker could change the members of your classes and do bad stuff with it. For example he could subclass your classes and send an email from one of the overridden methods with private data.

In this article, I show you how to turn an ordinary mutable classes into an immutable one.

A mutable class

Let’s imagine your boss wants a new class that represents a bill for an online shop. Here is a first example of a mutable class called Bill. This is of course not a realistic example of a real online shop. 🙂

In this version of the class, all the members can be changed after instances of the class have been created.

An immutable class

Let’s make this class immutable.

In this example, several changes have been made to make the class immutable:

  • The class is final. That means no subclasses can be created. A subclass of an immutable class can be made mutable again. As noted above, an attacker could use that to get to confidential data.
  • The variables are all final and cannot be changed after construction
  • In the constructor we use the import org.joda.time.DateTime class. This is a better version than the java.util.Date because it is immutable. Using a java.util.Date would be dangerous as it is a mutable class and we can’t control the calling thread (which might modify it).
  • There are no setter methods for the members.

This version of the Bill class is immutable. Now imagine your boss calls you and tells you that you need to implement another method which increased the amount of the bill after the Bill object was already created. At first you try to explain that changed the state of the class is not possible but your boss insists on this change.
You think a little bit and come up with this design of the new method

This does the trick. Instead of changing the internal state of the Bill object and using a void method, you create a completely new Bill object and return it. The caller of the addAmount method will have to use this new object if he wants to use the correct bill. This is similar to methods like replace of the String class. They don’t really change the string on which you called the method but return a new String object.

Using immutable collections in immutable classes

Now your boss comes again and tells you that the Bill object must also keep a list of orders.
In order to do that, first you have to make an immutable Order object.

The new version of the Bill object now looks like this:

This version uses a new final com.google.common.collect.ImmutableList. This
is part of the Google Guava library where there are many different immutable collections (see here for more details: ImmutableCollectionsExplained .

The addOrder method creates a new com.google.common.collect.ImmutableList and then creates a new Bill object, similar to the addAmount method.
The caller of the addOrder method will have to use the newly returned object to use the correct Bill instance.

Note: com.google.common.collect.ImmutableList implements the java.util.List interface but I normally use the com.google.common.collect.ImmutableList in the type declaration to make it clear that I want this object to be immutable.

What about performance?

You may wonder about performance? The creation of new ones in the constructors or methods like addAmount or addOrder are more expensive than in a mutable class. In some situations this can be a disadvantage of your immutable classes but in most projects this probably won’t matter. To be sure, you should of course profile and test your application.

If possible immutable classes are preferred for thread safety and security. If you come from functional languages like Haskell or Lisp, this will feel very natural to you anyway. If you’ve been using mutable classes mostly, this may require some new thinking but could greatly improve your code. Of course you always have to decide for each class you develop if it makes sense.