What are Immutable objects? What is Immutability in general? In this post, I will explain about Immutable objects and Immutability in general, while also highlighting their pros and cons as compared to Mutable objects.
NOW, WHAT ARE IMMUTABLE OBJECTS ?
Any object whose state can’t be changed once it is created or instantiated is called as Immutable object. Similarly, any object whose state can be changed once it is created or instantiated is called as Mutable object. But in general, we often use the term Immutability for a class which means any class whose objects’ state can’t be changed once they are created is called an Immutable class. String is the best example of an Immutable class. All wrapper classes are also Immutable e.g. Boolean, Long, Double etc. One thing to note here is that, these classes have member functions that look as if they change the state of the object but actually they don’t. For example, toLower() function in String class doesn’t change the state/content of the string object on which it is called. It just returns a new String object with content in lower case. This statement applies to other functions like toUpper(), replace() etc.
WHY CREATE IMMUTABLE OBJECTS ?
Here are the major advantages or scenarios when an Immutable object is preferred over Mutable objects in Java:
- When a developer doesn’t want his objects to change when it is passed to different functions or modules. More precisely, he/she might only want others to get the state of the object and not modify the state of the object. It could be due to security reasons as well.
- When a developer wants to avoid or reduce concurrency issues when an object is shared across multiple threads. If an object is simultaneously read and written by multiple threads, there are high chances of a race condition occurring. The code is very likely to behave unexpectedly. One simple way to avoid race condition is to make the class Immutable. Any changes to the shared object would only return a new object.
- When a developer wants to create a pool of objects. The best example is String pool in Java that is maintained in PermGen space. Since the object is intended to be used by multiple threads/classes/methods, it can’t be made Mutable because if one thread changes the state of the object, the other thread would see it immediately which might be unexpected. It is, therefore. necessary to make the class Immutable for implementing a pool containing objects of that class.
- When a developer wants to use the object as the key in a HashMap. Best example is the String class which is used as the key in HashMap most of the time. Since the HashMap works on the hashing concept (which returns or is supposed to return a unique int value for every single object based on the object’s state), the state of the object can’t be changed once its hash value is generated or used by the HashMap. Actually, when the object is inserted into the HashMap, it’s hash value is generated to create a bucket. When the object is retrieved later on, the hash value is generated again and searched in the bucket. If the object’s state changes after insertion and before retrieval, the generated hash value would not match the previous hash value and retrieval would not return any object even if it was stored. It is, therefore, necessary to make the class Immutable if it is intended for use as a key in a HashMap. This statement applies to other Collection classes also that use hashing concept like HashSet.
DISADVANTAGES OF IMMUTABLE OBJECTS
One major disadvantage of using Immutable objects in Java is that they create unnecessary objects. For example, if you have a String object. Any change or function call that you make to that object creates a new object. The bigger issue is that many developers are not aware of this. Concatenating numerous string objects in Java creates other numerous objects just because String is Immutable. In that case, it is preferred to use StringBuilder or StringBuffer classes. But any developer should keep this point in mind that making lot of changes or function calls to an Immutable object creates unnecessary objects which could cause memory issues.