tags:

views:

74

answers:

4

You often read about immutable objects requiring final fields to be immutable in Java. Is this in fact the case, or is it simply enough to have no public mutability and not actually mutate the state?

For example, if you have an immutable object built by the builder pattern, you could do it by having the builder assign the individual fields as it builds, or having the builder hold the fields itself and ultimately return the immutable object by passing the values to its (private) constructor.

Having the fields final has the obvious advantage of preventing implementation errors (such as allowing code to retain a reference to the builder and "building" the object multiple times while in fact mutating an existing object), but having the Builder store its data inside the object as it is built would seem to be DRYer.

So the question is: Assuming the Builder does not leak the Object early and stops itself from modifying the object once built (say by setting its reference to the object as null) is there actually anything gained (such as improved thread safety) in the "immutability" of the object if the object's fields were made final instead?

+1  A: 

An Object can certainly have mutable private fields and still work as an immutable object. All that matters to meet the contract of immutability is that the object appears immutable from the outside. An object with non-final private fields but no setters would for example satisfy this requirement.

In fact, if your encapsulation is right then you can actually mutate the internal state and still operate successfully as an "immutable" object. An example might be some sort of lazy evaluation or caching of data structures.

Clojure for example does this in its internal implementation of lazy sequences, these objects behave as if they are immutable but only actually calculate and store future values when they are directly requested. Any subsequent request retrieves the stored value.

However - I would add as a caveat that the number of places where you would actually want to mutate the internals of an immutable object are probably quite rare. If in doubt, make them final.

mikera
"An object with non-final private fields but no setters would for example satisfy this requirement" - This by itself does not guarantee immutability. Getters can return data member references, and these can be modified by the caller.
Eyal Schneider
@Eyal: true - though the references themselves would be immutable. If you constructed the object with immutable members then immutability would hold all the way down. Alternatively, creating an immutable composition or collection of mutable objects does make sense in some contexts.
mikera
Should add - different people have slightly different definitions of immutability... mine is "immutability from the perspective of the observer" which I think is the most useful but I've also heard people define immutability as absolutely no change whatsoever allowed.
mikera
+2  A: 
erickson
A: 

I think you would just need to consider the environment its running in and decide if frameworks that use reflection to manipulate objects are a hazard.

One could easily cook up an oddball scenario where a supposedly immutable object gets clobbered via a POST injection attack because of a web binding framework that's configured to use reflection instead of bean setters.

Affe
A: 

You definitely can have an immutable object with non-final fields.

For example see java 1.6 implementation of java.lang.String.

Alexander Pogrebnyak