Benefits of immutability in a software development

15 January 2019

The idea of immutability is widely spread. However, I think it is quite rarely used in real programming among Java developers. In this article, I’m going to explain the benefits of immutable objects.

The first advantage of immutability is avoiding side effects. Let’s take a look at an example:

public static double average(Collection<Double> numbers)

When we look at the signature of the method, it seems that everything is OK. The method takes a collection of doubles and returns an average. However, nothing prevents a developer from implementing the method in this way:

public static double average(Collection<Double> numbers) {
    if (numbers == null || numbers.isEmpty()) {
      throw new IllegalArgumentException();
    }
    double average = numbers.stream()
        .mapToDouble(Double::doubleValue)
        .average()
        .getAsDouble();
    numbers.clear();
    return average;
}

Therefore, this method is not a pure function. It doesn’t have a boundary between arguments and the result, because an argument is changed as well. In order to ensure nothing like that will happen we should pass an immutable collection.

Another reason why immutability is great is connected with different collections. Let’s assume that we have a Point class:

@Data
@AllArgsConstructor
public class Point {
   private int x,y;
}

What will happen if we put an instance of the Point class into HashMap and later on we change the value of x or y? Let’s check:

Map<Point, String> pointLabelMap = new HashMap<>();
Point point = new Point(3, 4);
pointLabelMap.put(point, "Mutable point");
System.out.println("Label: " + pointLabelMap.get(point));
point.setX(0);
System.out.println("Label: " + pointLabelMap.get(point));

And this is the result:

Label: Mutable point
Label: null

After the point instance had been changed, the hashcode of that object was different, therefore it couldn’t be found in HashMap (a bucket not found). Similar side effects can be observed when it comes to using tree-based structures like TreeMap. Once an object was put in a structure. The order of objects is not changed if the object was modified. Because of that, it is highly recommended to use an immutable object as a key in map structures.

Read also: What is the distinction between Java and JavaScript?

Another gain from immutability is the fact that we don’t need any more defensive copies. I’m pretty sure that a lot of programmers who remember java.util.Calendar and java.util.Date remember how they had to make a lot of copies of those objects. For instance, let’s assume that we need to create a DTO class which represents delivery data. And we have a field which tells us when we, a client, should expect items to be delivered. Usage of java.util.Date calendar will force us to create a defensive copy of the date. It’s because it can be used later on in some other computations.

Many people will say that creating immutable objects will lead to a garbage collector overhead. However, this is not true at all. The first reason is that we don’t need defensive copies. As I pointed out before. And it is much easier to delete an object from a heap than an old one.  When we create a new object, which has almost all references as an old object and one or a few new references to new objects, it is better than having an older object which has references to new objects. We are also able to use an object pool and flyweight pattern to manage those value objects. We all know a very good example: String class.

The last benefit I would like to describe is thread-safety – objects which are immutable are perfectly thread-safe. There are no race conditions on the mutating state of the object, and the final keyword ensures visibility for other threads.

Of course, there are areas where immutability is not the best option. The first of them is GUI – where mutation of a state and a graphical interface go naturally together. Sometimes we also need mutable objects when we use concurrency. For instance, the BlockingQueue class should be mutable in order to work correctly. Mutable data structures are often very useful when we need high performance. There are more situations when mutability is better than immutability. However, I still believe that immutability is great when it comes to proceeding data e.g. in business applications.

I hope I’ve persuaded you to change your way of thinking about using immutability and to take full advantage of its the benefits.

Read also: Backend Development

Cookies Policy

Our website uses cookies. You can change the rules for their use or block cookies in the settings of your browser. More information can be found in the Privacy Policy. By continuing to use the website, you agree to the use of cookies.
https://www.efigence.com/privacy-policy/