Immutable means unchangeable.In Java,when you have a reference to an instance of an object, the contents of that instance cannot be altered, that is objects that you cannot change the contents after they have been set.
All of the java.lang package wrapper classes are immutable: Boolean, Byte, Character, Double, Float, Integer, Long, Short, String.
How to show java.lang.String are immutable
1 2 3 4 |
String myString = new String( "old String" ); System.out.println( myString ); myString.replaceAll( "old", "new" ); System.out.println( myString ); |
output:
1 2 |
old String old String |
However, for the code:
1 2 3 4 |
String myString = new String( "old String" ); System.out.println( myString ); myString = new String( "new String" ); System.out.println( myString ); |
the output will be:
1 2 |
old String new String |
Why immutable?
Immutable types are a good thing generally:
- They work better for concurrency (you don’t need to lock something that can’t change!)
- They reduce errors: mutable objects are vulnerable to being changed when you don’t expect it which can introduce all kinds of strange bugs (“action at a distance”)
- They can be safely shared (i.e. multiple references to the same object) which can reduce memory consumption and improve cache utilisation.
- Sharing also makes copying a very cheap O(1) operation when it would be O(n) if you have to take a defensive copy of a mutable object. This is a big deal because copying is an incredibly common operation (e.g. whenever you want to pass parameters around….)
Make a class immutable by following these guidelines :
- Don’t provide “setter” methods — methods that modify fields or objects referred to by fields.
- Make all fields final and private.
- Don’t allow subclasses to override methods. The simplest way to do this is to declare the class as final. A more sophisticated approach is to make the constructor private and construct instances in factory methods.
- 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 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.