One of the preferred questions of the interviewers is
What is an immutable object? Can you write an immutable class?
In Java, an immutable object is the object which once created it cannot be modified. Respectively, an immutable class is a class whose objects cannot be modified once created. The most common example of immutable class in Java is the String class (which btw, is marked as final to prevent subclassing. This choose was made in order to restrict subclassing from altering the immutability of the parent class). To achieve the immutable functionality of a class you declare it’s members as private and modify them only in the constructor of the class.
A strategy to defining immutable objects could be defined as follow:
- do not provide setter methods in your class (only getters are allowed);
- mark all fields as private and final;
- do not allow subclasses to override the methods in your class. One possible way of achieving this behavior is to mark your class as final;
- do not share references to the mutable object. Create copies of them.
An example of immutable class
Let see first, the Address object which will use as field in our immutable object:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
package org.programmers.code; public class Address { private String country = "RO"; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } |
The immutable class will be defined as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
package org.programmers.code; public final class ImmutableClass { // strings are immutable objects. As well as primitives and wrapper classes. private final String name; private final String profileLink; // Address is not immutable. Will return a copy in the getter method, and class's constructor too. private final Address address; public ImmutableClass(String name, String profileLink, Address address) { this.name = name; this.profileLink = profileLink; // make a copy to ensure Address state won't change Address addressCopy = new Address(); addressCopy.setCountry(address.getCountry()); this.address = addressCopy; } public String getName() { return name; } public String getProfileLink() { return profileLink; } public Address getAddress() { Address addressCopy = new Address(); address.setCountry(address.getCountry()); return addressCopy; } } |
Why want to use immutable object
Let’s extend this topic purpose and talk about the advantages of the immutable objects vs. mutable objects. They provide concurrency and multithreading advantages over the mutable objects. For example, immutable object can be shared between multiple threads without providing an external synchronization. In other words, immutable objects are by default thread-safe.
Another advantage is that immutable classes can be used as keys in Map or Set. This is because they eliminates the possibility of data becoming unreachable.
Key take away:
- Any modification to an immutable object will result in the creation of a new immutable object.
- Objects of java.lang.String class are the most know examples of immutable objects. Any change on existing string object will result in another string.