An immutable object is one whose externally visible state cannot change after it is instantiated. The String, Integer, and BigDecimal classes in the Java class library are examples of immutable objects — they represent a single value that cannot change over the lifetime of the object.
Mutuable Objects are ones whose state or data can be changed at any point of time. StringBuffer is an example of Mutable object.
Benefits of immutability
Immutable classes, when used properly, can greatly simplify programming. They can only be in one state, so as long as they are properly constructed, they can never get into an inconsistent state. so the advantages are
* You can freely share and cache references to immutable objects without having to copy or clone them;
* Immutable classes generally make the best map keys.
* they are inherently thread-safe, so you don’t have to synchronize access to them across threads.
Better Candidate for Caching
Because there is no danger of immutable objects changing their value, you can freely cache references to them and be confident that the reference will refer to the same value later. Similarly, because their properties cannot change, you can cache their fields and the results of their methods.
Automatically Thread Safe, No Need to Synchronize
Most thread-safety issues arise when multiple threads are trying to modify an object’s state concurrently (write-write conflicts) or when one thread is trying to access an object’s state while another thread is modifying it (read-write conflicts.) To prevent such conflicts, you must synchronize access to shared objects so that other threads cannot access them while they are in an inconsistent state. This can be difficult to do correctly, requires significant documentation to ensure that the program is extended correctly, and may have negative performance consequences as well. As long as immutable objects are constructed properly (which means not letting the object reference escape from the constructor), they are exempt from the requirement to synchronize access, becuase their state cannot be changed and therefore cannot have write-write or read-write conflicts.
Makes the Best for Keys in Collection
Immutable objects make the best HashMap or HashSet keys. Some mutable objects will change their hashCode() value depending on their state (like the StringHolder example class in Listing 2). If you use such a mutable object as a HashSet key, and then the object changes its state, the HashSet implementation will become confused — the object will still be present if you enumerate the set, but it may not appear to be present if you query the set with contains(). Needless to say, this could cause some confusing behavior.
Here is an Example below
Guidelines for writing immutable classes
Writing immutable classes is easy. A class will be immutable if all of the following are true:
* All of its fields are final
* The class is declared final
* The this reference is not allowed to escape during construction
* Any fields that contain references to mutable objects, such as arrays, collections, or mutable classes like Date:
o Are private
o Are never returned or otherwise exposed to callers,if returned a defensive copy of it should be returned
o Are the only reference to the objects that they reference
o Do not change the state of the referenced objects after construction
class ImmutableArrayHolder {
private final int[] theArray;
// Right way to write a constructor -- copy the array
public ImmutableArrayHolder(int[] anArray) {
this.theArray = (int[]) anArray.clone();
}
// Wrong way to write a constructor -- copy the reference
// The caller could change the array after the call to the constructor
//public ImmutableArrayHolder(int[] anArray) {
// this.theArray = anArray;
//}
// Right way to write an accessor -- don't expose the array reference
public int getArrayLength() { return theArray.length }
public int getArray(int n) { return theArray[n]; }
// Right way to write an accessor -- use clone()
public int[] getArray() { return (int[]) theArray.clone(); }
// Wrong way to write an accessor -- expose the array reference
// A caller could get the array reference and then change the contents
//public int[] getArray() { return theArray }
}
References :
http://www.javapractices.com/topic/TopicAction.do?Id=29
http://www.ibm.com/developerworks/java/library/j-jtp02183.html
http://www.javaranch.com/journal/2003/04/immutable.htm