Having practiced a lot of functional programming recently (I've just finished the Functional Programming Principles in Scala online course on Coursera, and I loved it!), I came (again) across the topic of immutability
For those who don't know the word, an immutable object is an object whose state can't change after it has been built (i.e. you cannot add elements to a collection). In some languages such as Scala, immutability is achieved without too much hassle (actually Scala collections are immutable by default, unless you specifically choose to import their mutable version), for other languages such as Java there are few tricks to make objects immutable (using constructor / builder objects for setting up state, using Immutable Collections to build your collections, have no setters / all final fields, marking its class as final and so on).
Even if constructing an object to be immutable is not immediate, I always try to make the objects I wrote immutable, and I think you should as well! There are few reasons for this:
- An immutable object is inherently thread-safe. Since its state cannot be changed, there are no race conditions when trying to access the object concurrently, hence it can be shared freely without the need for any synchronisation on it.
- An immutable object is constant. This leads to various advantages, such as it can be used as a key to a map. If you're using a map that calculates the hash of its key, an immutable object will always have the same hash. It can be cached, and it allows you to truly rely on the hash to retrieve an object (what would happen if you use a mutable object as a key then you change your state?)
- It's easier to reason with an immutable object, as you know that once it's been created its state will be always the same. You can avoid defensive code practices (copy constructors, copy of fields) when you deal with immutable objects.
- It forces you to write methods which don't have side effects: if you pass an immutable object as a parameter to a method, you are certain that the object won't be in a different after the method has been executed. This makes debugging issues much easier!
As I said before, there are libraries such as Guava that makes this task easier. Unfortunately, in some situations making an object immutable is not possible, but in that case we should aim to reduce mutability as much as we can.