In this article we
will discuss about following topic
è What
is an Immutable Class ?
è How to create
Immutable class ?
è Write a Custom
immutable class ?
è What are the advantage
of Immutability ?
è Why
is it important in multi-threading context ?
è What are semantics for
writing an Immutable Class in java ?
What is an Immutable Class ?
As
per Oracle docs , An Immutable class is a class if its state of object cannot change after it is constructed. It
means any modification of Immutable
object will be another immutable object. Since the state of the immutable objects
can not be changed once they are created they are automatically synchronized/thread-safe.All wrapper classes
in java.lang are immutable String,
Integer, Boolean, Character, Byte, Short, Long, Float, Double, BigDecimal,
BigInteger.
Why is String immutable?
Example
of Immutable class:
·
java.lang.String
·
The wrapper classes
for the primitive types: java.lang.Integer, java.lang.Byte,
java.lang.Character, java.lang.Short, java.lang.Boolean, java.lang.Long,
java.lang.Double, java.lang.Float
·
java.lang.StackTraceElement
(used in building exception stacktraces)
·
Most enum classes are
immutable, but this in fact depends on the concrete case. (Don't implement
mutable enums, this will screw you up somewhen.) I think that at least all enum
classes in the standard API are in fact immutable.
·
java.math.BigInteger
and java.math.BigDecimal (at least objects of those classes themselves,
subclasses could introduce mutability, though this is not a good idea)
·
java.io.File. Note
that this represents an object external to the VM (a file on the local system),
which may or may not exist, and has some methods modifying and querying the
state of this external object. But the File object itself stays immutable. (All
other classes in java.io are mutable.)
·
java.awt.Font -
representing a font for drawing text on the screen (there may be some mutable
subclasses, but this would certainly not be useful)
·
java.awt.BasicStroke -
a helper object for drawing lines on graphic contexts
·
java.awt.Color - (at
least objects of this class, some subclasses may be mutable or depending on
some external factors (like system colors)), and most other implementations of
java.awt.Paint .
How to create Immutable class ?
The
steps to create a Immutable class in
Java -
1)
Mark
the class final .
2)
Mark
the fields private and final.
3)
Set
the values of properties of the class final and Private , i.e do not use any setter
methods,.
4)
Do
not change the state of the objects in
any methods of the class. If the
instance fields includes references to mutable objects, don’t allow those
objects to be changed.
5)
Don’t
provide methods that modified the mutable objects.
6) Don't share references to
the mutable objects. Never store references to external, mutable objects passed
to the constructor; if necessary, create copies, and store references to the
copies. Similarly, create copies of your internal mutable objects when
necessary to avoid returning the originals in your methods.
Write a Custom
immutable class ?
Example of Immutable class in Java:
package Java91.blogspot.in;
public final class TestImmutableClass {
private final Integer id;
private final String name;
private final String password;
public TestImmutableClass(Integer id, String name, String
password) {
super();
this.id = id;
this.name = name;
this.password = password;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
}
What are the advantage of Immutability ?
1.
Immutable objects are thread-safe so
you will not have any synchronization issues.
2.
Immutable objects are good Map keys
and Set elements, since these typically do not change once
created.
3.
Immutability makes it easier to
write, use and reason about the code (class invariant is established once and
then unchanged)
4.
Immutability makes it easier to
parallelize your program as there are no conflicts among objects.
5.
The internal state of your program
will be consistent even if you have exceptions.
6.
References to immutable objects can
be cached as they are not going to change.
In
Java the good programming practice is one should try to use immutable objects
as far as possible.
Immutability can have a performance cost, since when an object cannot be
mutated we need to copy it if we want to write to it.
By Joshua Bloch
Classes should be immutable unless
there's a very good reason to make them mutable....If a class cannot be made
immutable, limit its mutability as much as possible.
Why is it important in
multi-threading context ?
As we all know if an object is Immutable , it is thread safe. But some scenario
It is not thread safe . I am going to explain why Immutable class not fully thread
safe .
Let look into the String class code:
public class String {
private final char value[];
/** Cache the
hash code for the string */
private int hash; // Default to 0
public String(char[] value) {
this.value = Arrays.copyOf(value, value.length);
}
public int hashCode() {
int h = hash;
if (h == 0
&& value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
}
String is considered immutable. Looking at its
implementation, we can deduce one thing: an immutable string can change its
internal state (in this case, the hashcode which is lazy loaded) as long as it
is not externally visible.Now I am going to rewrite the hashcode method in a
non-thread safe way:
public int hashCode() {
if (hash == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
hash = 31 * hash + val[i];
}
}
return hash;
}
As you can see, I have removed the local variable h and I
have instead affected the variable hash directly. This implementation is NOT
thread safe! If several threads call hashcode at the same time, the returned
value could be different for each thread. The question is, 'is this class
immutable?' Since two different threads can see a different hashcode, in an
external point of view we have a change of state and so it is not immutable.We
can so conclude that String is immutable because it is thread safe and not the opposite. So... What's
the point of saying "Use an immutable object, it is thread-safe! But take
care, you have to make your immutable object thread-safe!"?
What are semantics for
writing an Immutable Class in java ?
1.
Immutable objects are thread-safe so
you will not have any synchronization issues.
2.
Immutable objects are good Map keys
and Set elements, since these typically do not change once
created.
3.
Immutability makes it easier to
write, use and reason about the code (class invariant is established once and
then unchanged)
4.
Immutability makes it easier to
parallelize your program as there are no conflicts among objects.
5.
The internal state of your program
will be consistent even if you have exceptions.
6.
References to immutable objects can
be cached as they are not going to change.