Mutability in Java
Understanding Mutability
Reference URL: http://web.mit.edu/6.005/www/fa15/classes/09-immutability/
Immutable: An object that will always have the same value after it is created. Its value / contents cannot be changed.
Mutable objects on the other hand have methods that change the value of the object.
The
String
object is an example of an immutable object in Java. To add something to the end of aString
, you have to create a new String object.The
StringBuilder
is an example of a mutable type. It has methods to delete parts of the string, isert or replace characters.
The differences between mutability and immutability does not matter much when there is only one reference to an object. There are big differences in how they behave when there are other references to the same object. Let’s take the examples given below:
String s = "";
for (int i = 0; i < n; i++) {
s = s + n;
}
Using immutable strings, many temporary copies of the string variable are created. This has an impact on performance.
StringBuilder sb = new StringBuilder();
for (int i = 0; i < n; i++) {
sb.append(String.valueOf(n));
}
String s = sb.toString();
The mutable StringBuilder
is designed to minimize this copying by using an internal data structure that avoids copying the string at every iteration, until the very end when the final String
is required, with the toString()
call. Hence, in this case, getting good performance is one reason why we use mutable objects. Another reason is the convenience of sharing. Two parts of a program can communicate more conveniently by sharing a common mutable data structure.
Risks behind mutation
Since mutable objects are more powerful than immutable objects, wouldn’t it be better to just use
StringBuilder
instead ofString
?NO!!. The reason is that immutable* types are safer from bugs*, **easier to understand and more ready for change compared to immutable objects.
This is the reason why we use the
String
object!
Risks associated with mutable objects:
Passing mutable values to a function: The function can change the value of the mutable object. The calling code does not know if the object has been changed or not.
Returning mutable values from a function: After a mutable object has been returned, it is possible that the calling function may inadvertently change the value of this object.
Useful immutable types
Some commonly used immutable types in the Java API are as given below:
All primitive data types and primitive wrappers are immutable. For large numbers,
BigInteger
andBigDecimal
are immutable.Instead of
Date
, use the immutablejava.time
type for timekeeping.Java’s collection types -
List
,Set
,Map
, etc. are all mutable. You can use their unmodifiable views such asCollections.unmodifiableList
,Collections.unmodifiableSet
andCollections.unmodifiableMap
. These provide a wrapper around the underlying list / set / map, which can be passed on to clients that require a reference.
Note: Java gives us the ability to make variables immutable with the final
keyword. This also serves as a means of documentation and increases code readability.