I\'m trying to get my head around mutable vs immutable objects. Using mutable objects gets a lot of bad press (e.g. returning an array of strings from a method) but I\'m hav
If a class type is mutable, a variable of that class type can have a number of different meanings. For example, suppose an object foo
has a field int[] arr
, and it holds a reference to a int[3]
holding the numbers {5, 7, 9}. Even though the type of the field is known, there are at least four different things it can represent:
A potentially-shared reference, all of whose holders care only that it encapsulates the values 5, 7, and 9. If foo
wants arr
to encapsulate different values, it must replace it with a different array that contains the desired values. If one wants to make a copy of foo
, one may give the copy either a reference to arr
or a new array holding the values {1,2,3}, whichever is more convenient.
The only reference, anywhere in the universe, to an array which encapsulates the values 5, 7, and 9. set of three storage locations which at the moment hold the values 5, 7, and 9; if foo
wants it to encapsulate the values 5, 8, and 9, it may either change the second item in that array or create a new array holding the values 5, 8, and 9 and abandon the old one. Note that if one wanted to make a copy of foo
, one must in the copy replace arr
with a reference to a new array in order for foo.arr
to remain as the only reference to that array anywhere in the universe.
A reference to an array which is owned by some other object that has exposed it to foo
for some reason (e.g. perhaps it wants foo
to store some data there). In this scenario, arr
doesn't encapsulate the contents of the array, but rather its identity. Because replacing arr
with a reference to a new array would totally change its meaning, a copy of foo
should hold a reference to the same array.
A reference to an array of which foo
is the sole owner, but to which references are held by other object for some reason (e.g. it wants to have the other object to store data there--the flipside of the previous case). In this scenario, arr
encapsulates both the identity of the array and its contents. Replacing arr
with a reference to a new array would totally change its meaning, but having a clone's arr
refer to foo.arr
would violate the assumption that foo
is the sole owner. There is thus no way to copy foo
.
In theory, int[]
should be a nice simple well-defined type, but it has four very different meanings. By contrast, a reference to an immutable object (e.g. String
) generally only has one meaning. Much of the "power" of immutable objects stems from that fact.