Immutable class is a class which when once created, it's contents cannot be changed under any circumstances. Immutable objects are the objects whose state cannot be changed once constructed. Say for instance 'String class'.
To create an immutable class one needs to follow the following steps as mentioned below:
Create a final class.
Set the values of properties using constructor only.
Make the properties of the class final and private.
Do not provide any setters for these properties.
If the instance fields include references to mutable objects, don't allow those objects to be changed
Don't provide methods that modify the mutable objects.
Don't share references to the mutable objects. Never store references to external, mutable objects that are passed to the constructor; if necessary, create copies and store references to the copies. Similarly, create copies of your internal mutable objects when it is necessary to avoid returning the originals in your methods.
public final class FinalPersonClass {
private final String name;
private final int age;
public FinalPersonClass(final String name, final int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
True. Since the state of the immutable objects cannot be changed once they are created they are automatically synchronized and are thread-safe.
All wrapper classes in java.lang are immutable which includes String, Integer, Boolean, Character, Byte, Short, Long, Float, Double, BigDecimal, BigInteger.
Immutable objects are thread-safe by default and apart from this, the overhead caused due to the use of synchronization is avoided.
Once created the state of the immutable object cannot be changed so there is no possibility of them getting into an inconsistent state.
The references to the immutable objects can be easily shared or cached without any need to copy or clone them as there state can never be changed after its construction.
The immutable objects can be best used as the keys of a map.
Here is complete code which gives an example of writing immutable class in Java. We have followed simplest approach and all rules for making a class immutable, which includes making class final to avoid putting immutability at risk due to Inheritance and Polymorphism.
public final class Contacts{
private final String name;
private final String mobile;
public Contacts(String name, String mobile) {
this.name = name;
this.mobile = mobile;
}
public String getName() {
return name;
}
public String getMobile() {
return mobile;
}
}
This Java class is immutable because it's state cannot be changed once it has been created. One can see that all of it's fields are final.
This is one of the most simple way of creating immutable class in Java, where all fields of class also remains immutable like String in above case.
Sometimes one may need to write immutable class which includes mutable classes like java.util.Date.Despite storing 'Date' into a 'final' field it can be modified internally if internal date is returned to the client.
In order to preserve immutability in such cases,its advised to return copy of original object, which is also one of the Java's best practice.
Here is another example of making a class immutable in Java, which includes mutable member variable.
public final class ImmutableReminder {
private final Date remindingDate;
public ImmutableReminde (Date remindingDate) {
if(remindingDate.getTime() < System.currentTimeMillis()) {
throw new IllegalArgumentException("Can not set reminder” +
“ for past time: " + remindingDate);
}
this.remindingDate = new Date(remindingDate.getTime());
}
public Date getRemindingDate() {
return (Date) remindingDate.clone();
}
}
Some of the advantages of using immutable class are as follows:
Thread safe - Immutable classes are thread safe, they will never create race condition.
Key in HashMap - Immutable classes can be used as key in Map (HashMap etc.)
HashCode is cached - JVM caches the HashCode of Immutable classes used in application.This will avoid JVM from calculating hashcode again. Hence, performance of application is improved significantly.
Immutable class throws Exception - If Immutable class throws Exception, they are never left in undesirable state.
As mentioned earlier Immutable classes offers several benefits, here are some of them as mentioned below:
Immutable objects are by default thread safe and can be shared without synchronization in concurrent environment.
Immutable object simplifies development because its easier to share between multiple threads without external synchronization.
Immutable objects boost performance of Java applications by reducing synchronization in code.
Another important benefit of Immutable objects is its reusability. One can cache Immutable objects and reuse them just like String literals and Integers. One can use static factory methods to provide methods like valueOf(), which can return an existing Immutable object from cache, instead of creating a new one.