Immutable object
From Freepedia
In computer science, an immutable object, as opposed to a mutable object, is a kind of object whose internal states cannot be modified after it is created. An object can be immutable as whole or some attributes in the object may be immutable, as in C++'s const member data attribute. In some cases, an object is considered immutable while some attributes for internal use change (like for caching purpose) yet the state appears to be unchanging. The initial state of an immutable object is mostly set at its inception, but it can be set right before actual use of the object.
Immutable objects are often useful because when an object is known to be immutable, some of costly operations for copying and comparing may be omitted altogether, simplifying the program code and speeding up its execution. Since sometimes making an object immutable costs in time and space, the use of immutable objects may not result in improvement. This is especially so when an object contains a large amount of data. Because of this, many languages allow for both immutable and mutable versions of objects.
Contents |
Background
In some languages, objects are handled as a reference. Java and many script languages like Python and Ruby are examples. In that case, it matters whether the state of object can vary or not since objects are shared via references.
If an object is known to be immutable, then instead of creating copies of the entire object, only copies of a reference to it need be made. Because a reference is very often much smaller than the object itself (typically only the size of a pointer), this results in savings of memory usage and boost in execution speed.
The above technique is much more difficult to use for mutable objects, because if any user of a reference to a mutable object changes it, all other users of that reference will see that change. If this is not the intended effect, it can be difficult to notify the other users to have them respond correctly. In such situations, copying of the entire object rather than the reference, known as defensive copy, is usually the easiest yet potentially costly solution. For a well-known technique that handles changes to mutable objects, see the discussion on the observer pattern.
Besides the efficiency in space and time, the use of immutable object can be quite useful in multi-threaded applications. This is because when an operation is to be executed against a piece of data that an immutable object represents then another thread can act on that same data without fear of it changing during its operation. Having such a property is called thread-safe.
The attempt to comprehensively use references in place of copies of equal objects is known as interning; two objects are equal if and only if their references, which are typically represented by integers, are equal. Some languages do this automatically; for example, Python automatically interns strings. If the algorithm which implements interning is guaranteed to do so in every case that it is possible, then comparing objects for equality is reduced to comparing their pointers, a substantial gain in speed for some applications. (Even if that algorithm is not guaranteed to be comprehensive, there still exists the possibility of a fast path case improvement when the objects are equal and use the same reference.) Interning is generally only useful for immutable objects.
Implementation
Immutability does not imply that the object as it is stored in the computer's memory is unwriteable. Rather, immutability is a compile-time construct that indicates what a programmer may do, not necessarily what he can do (by circumventing the type system or violating const correctness in C or C++).
A technique which blends the advantages of mutable and immutable objects, and supported in almost all modern hardware, is copy-on-write (COW). Using this technique, when a user asks the system to copy an object, it will instead merely create a new reference which, through hardware trickery, still points to that same object. As soon as a user modifies the object through a particular reference, a real copy is made by the system and that same reference will now refer to the new copy. The other users are unaffected, because they still refer to the original object. Therefore, under COW, all users appear to have a mutable version of their objects, although in the case that users do not modify their objects, the space-saving and speed advantages of immutable objects are retained. COW is popular in virtual memory systems because it allows them to save memory space in the core while still correctly handling anything an application program might do.
Example
For an object to be immutable, there has to be no way to change fields, mutable or not, and to access fields that are mutable. For example, using Java,
class Cart {
private final List items;
public Cart(List items) { this.items = items; }
public List getItems() { return items; }
public int total() { ... /* return sum of the prices */ }
}
An instance of this class is not immutable; one can add or remove items either by obtaining a field items by calling getItems() or retaining a list object passed when an object of this class is created. The following change mitigates this problem; thus, instances of this class would be immutable.
class ImmutableCart {
private final List items;
public ImmutableCart(List items) { this.items = Arrays.asList(items.toArray()); }
public List getItems() { return Collections.unmodifiableList(items); }
public int total() { ... /* return sum of the prices */ }
}
In C++, a const-correct implementation of Cart would allow the user to declare new instances of the class const or mutable, as desired, by providing two different versions of the getItems() method. (Notice that in C++, which lacks automatic garbage collection, it is idiomatic to make a copy of the constructor parameter v rather than keeping only a reference to it, as in the Java code above. Therefore, the C++ code needs only to const-qualify the result of getItems(); it is not necessary — and in fact impossible! — to provide a specialized constructor for const instances.
template<typename T>
class Cart {
private:
vector<T> items;
public:
Cart(vector<T> v): items(v) {}
vector<T>& getItems() { return items; }
const vector<T>& getItems() const { return items; }
int total() const { ... /* return sum of the prices */ }
};
Usage
Strings or other concrete objects are typically expressed as immutable object to improve readability and runtime efficiency in object-oriented programming. In Python and Java, strings are immutable objects. Java has a class StringBuffer, which is a mutable object in addition to the immutable java.lang.String.
Other immutable classes in Java are Byte, Character, Short, Integer, Long, Float and Double.
Example in Java
A perfect example is the Java String object.
String abc = "ABC"; abc.toLower();
The method toLower() will have no impact on the data "ABC" that abc contains. What happens is that a new String object is instantiated and given the data "abc" during its construction. The returned String object will always refer to the string "abc". So to make the String identifier abc contain the data "abc" the following needs to be done :
abc = abc.toLower();
Now the identifier abc references a new String object that contains "abc". The String object's method never affects the data the String object contains, excluding the constructor. In Java and C#, this policy can be enforced by declaring the data using the final and readonly access modifiers, respectively.
Enforcement of the pattern can be checked by using specialized compilers (see for example [1]), and there is a proposal to add immutable types to Java.
Similar patterns are Immutable Interface and the Immutable Wrapper.
External links
- Article "Pattern: Immutable Object" by Nat Pryce
- Article "Java theory and practice: To mutate or not to mutate?" by Brian Goetz
- Article "Immutable objects" by vorthys on "Topcoder.com"
- Java Reference Java Practices: Immutable objects
- Descriptions from Portland Pattern Repository
- Chapter "Immutability of Objects" in the Common Lisp Interface Manager Specification
- Chapter "Immutable Classes" from a Sather manual
This article contains some material from the Perl Design Patterns Book.



