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?
Yes, you do get “thread safety” from
finalfields. That is, the value assigned to afinalfield during construction is guaranteed to be visible to all threads. The other alternative for thread safety is to declare the fieldsvolatile, but then you are incurring a high overhead with every read… and confusing anyone who looks at your class and wonders why the fields of this “immutable” class are marked “volatile.”Marking the fields
finalis the most correct technically, and conveys your intent most clearly. Unfortunately, it does make the builder pattern very cumbersome. I think it should be possible to create an annotation processor to synthesize a builder for an immutable class, much like Project Lombok does with setters and getters. The real work would be the IDE support needed so that you could code against the builders that don’t really exist.