Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I've recently begun adopting the best practice of designing my classes to be immutable per Effective Java [Bloch2008]. I have a series of interrelated questions about degrees of mutability and their consequences.

I have run into situations where a (Java) class I implemented is only "internally immutable" because it is immutable except that it uses (immutable) references to other mutable classes. To clarify, if the object were constructed with its references set to immutable classes, the class would be immutable.

  1. Do any of the benefits (see below) of immutable classes hold true even by only "internally immutable" classes?

  2. Is there an accepted term for the aforementioned "internal mutability"? Wikipedia's immutable object page uses the unsourced term "deep immutability" to describe an object whose references are also immutable.

  3. Is the distinction between mutability and side-effect-ness/state important?


The "Java Practices" site lists the following benefits of immutable classes:

  • are simple to construct, test, and use

  • are automatically thread-safe and have no synchronization issues

  • do not need a copy constructor

  • do not need an implementation of clone

  • allow hashCode to use lazy initialization, and to cache its return value

  • do not need to be copied defensively when used as a field

  • make good Map keys and Set elements (these objects must not change state while in the collection)

  • have their class invariant established once upon construction, and it never needs to be checked again

  • always have "failure atomicity" (a term used by Joshua Bloch) : if an immutable object throws an exception, it's never left in an undesirable or indeterminate state

share|improve this question

3 Answers 3

A Class isn't truly immutable if any of this children references aren't immutable as well. If your root Class has final references to all its instance variables and all those instance variables are immutable as well as all their children following this same restriction then you can say the root Class is immutable.

If any of the children references are non-final or any of the children instances are mutable then the containing Class is not immutable.

It doesn't matter about the internal immutablity whatever that means is anyone's guess, all that matters is that the public contract to the class immutability is kept. You can't have partial immutability anymore than you can be partially dead. Your class is either immutable or it isn't. And it isn't if any of its referred to classes or their classes, etc. are mutable.

If you have a graph and any of the members of the graph are mutable you can't deterministically say that you have an immutable state. Concurrency guarantees go out the window, .equals() and .hashCode() become non-deterministic and simple to test cloning and serializing go out the window as well.

If anything breaks this immutability contract you lose all the benefits of trying to maintain this immutability contract.

Simpler concurrency issues is a main motivational force of immutability.

Having side effect free code helps with predictability and maintainability. Since you don't have to wonder where things are getting mutated in the call tree because you know they can't be mutated.

Performance is another less important factor, in Java the JVM can make some highly optimized decisions about caching and other factors if it knows data can't change state. It does provide important hints to the compiler at compile time and the JIT algorithms at runtime.

share|improve this answer
4  
Re: "A Class isn't truly immutable if any of this children references aren't immutable as well", I don't think that's quite true. It depends on the semantics of the class and how it actually uses the non-immutable object. It may be OK for an "immutable" DocumentResultSet to have references to mutable Document objects, as long as those references are final. –  Darien Jun 22 '11 at 22:09
5  
This is a good answer, but why do you have to bold every single instance of mutable and immutable? Really makes it harder to read. –  Aaronaught Jun 23 '11 at 3:05
1  
@Darien I sort of agree. For example, I like to implement immutable lazy lists (handy for parsing) using an Iterator (the source), an ArrayList (elements that have been read from the source), and a position. In a sense the class is mutable because it references two mutable objects, but the mutability is completely encapsulated; the class fulfills the contract of an immutable structure. –  Daniel Jun 23 '11 at 4:01
2  
please correct your answer to reflect the fact that an immutable object can reference mutable objects as long as: 1. The references to its are not leaked; and 2. the immutable object cannot modify the mutable objects after construction. (Java Concurrency in Practice, Section 3.4 Immutability, Goetz2006) –  glenviewjeff Jun 29 '11 at 14:23
4  
A class can hold references to mutable objects and still be considered immutable if the purpose of the references is to IDENTIFY rather than CONTAIN the objects referred to thereby. For example, an immutable list of cars would be one that always refers to the same automobiles. If the fifth car on the list is a red car with VIN #24601, it might tomorrow be a blue car with VIN #24601, but it won't have any other VIN#. –  supercat Jul 17 '12 at 21:01

It doesn't really matter as long as the class you say is immutable cannot be observed to be mutable. E.g., memoisation uses mutation but a memoised value can be treated as immutable for all intents.

If I can't tell that your object uses mutable variables internally then it doesn't compromise my program and I can compose it with other objects as usual.

share|improve this answer

Immutability is useful when designing concurrent applications because of the object state guarantees it provides. It's also quite useful for Sets and as Map keys... As far as i am concerned there's no choice between immutability and mutability. As an example, in a multithreaded Bank application, an Account object cannot be made immutable because its a dynamic entity which changes overtime and its unique to one holder. However a Discount or APR can be designed as an Immutable object because they do not vary beyond definition. In short your problem domain will decide how you model your objects. Too many times Java programmers write code for "Gang Of Four" as opposed to coding to customer's requirement.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.