An immutable class is a class whose instances cannot be modified. All of the information contained in each instance is provided when it is created and is fixed for the lifetime of the object.
The biggest advantage of immutable objects is that they are inherently thread-safe; and therefore they do not require any synchronization. Therefore, immutable objects can be shared freely. Immutable classes are easier to design, implement, and use in comparison to mutable classes. They are less prone to error and are more secure.
To make a class immutable, follow the following rules:
1. Don’t provide any mutator methods, i.e. the methods that modify the object’s state.
2. Ensure that the class can’t be extended. This prevents careless or malicious
subclasses from compromising the immutable behavior of the class by behaving
as if the object’s state has changed. Preventing subclassing is generally accomplished
by making the class final or having a private constructor with a public static factory method.
3. Make all fields final. It is necessary to ensure correct behavior if a reference
to a newly created instance is passed from one thread to another without
Synchronization.
4. Make all fields private. This prevents clients from obtaining access to mutable
objects referred to by fields and modifying these objects directly.
5. Ensure exclusive access to any mutable components. If the class has any
fields that refer to mutable objects, ensure that clients of the class cannot obtain
references to these objects. Make defensive copies and return them instead.
Lets Take an example:
public final class Planet {
public Planet (double masss, String namee, Date datee) {
mass = masss;
name = namee;
//Make a defensive copy of the Mutable object Date
date = new Date(datee.getTime());
}
public double getMass() {
return mass;
}
public String getName() {
return name;
}
/**
* Returns a defensive copy of mutable object
*/
public Date getDate() {
return new Date(date.getTime());
}
private final double mass;
private final String name;
private final Date date;
}
|
The above code snippet is an example of an Immutable class. Notice, how we have made defensive copies of the mutable state ‘date’.
The only real disadvantage of immutable classes is that they require a
separate object for each distinct value. Creating these objects can be costly,
especially if they are large.
As discussed in rule 2 above, one alternative of creating an immutable object is to use a public static factory method to return the immutable instances rather than using a constructor. The real advantage that you get out of this approach is the flexibility of creating strategies like, reusing instances or caching instances etc instead of creating a new instance every time. Sometimes, this flexibility also aids performance. Static factory is a preferred way of creating immutable objects.