[concurrency-interest] Joda-Time immutability

Mark Thornton mthornton at optrak.com
Tue Jun 21 04:11:56 EDT 2011

On 21/06/11 07:27, Mark Thornton wrote:
> On 20/06/11 11:33, Stephen Colebourne wrote:
>> In Joda-Time way back when we structured the code in a complex manner
>> and then claimed immutability. This is causing difficulty to try and
>> obey proper immutability standards, and I'd like any ideas on fixes.
>> Consider the "immutable" class DateTime. The hierarchy is as follows:
>> AbstractInstant
>> AbstractDateTime
>> BaseDateTime
>> DateTime / MutableDateTime
>> https://github.com/JodaOrg/joda-time/tree/master/src/main/java/org/joda/time 
>> https://github.com/JodaOrg/joda-time/tree/master/src/main/java/org/joda/time/base 
>> The two Abstract prefixed classes are not an issue, as they just share
>> code and contain no state. However the BaseDateTime contains all the
>> state (and DateTime/MutableDateTime contain no state).
>> As a result of this (bad) design, the instance variables in
>> BaseDateTime are not final (as they need to be mutated by the
>> MutableDateTime subclass). The DateTime ("immutable") subclass is thus
>> storing its state in regular mutable variables in BaseDateTime. Under
>> the memory model, claiming DateTime as immutable is wrong.
> A possible solution:
> Make the fields in BaseDateTime final.
> DateTime is left unchanged.
> Duplicate the fields in MutableDateTime with getter/setters referring 
> to the new (mutable) fields.
> Add a readObject method to MutableDateTime which calls 
> ObjectInputStream.readFields. If the new fields are present (test 
> using GetFields.defaulted) then we are restoring from a serialization 
> of the new form of the class; just restore them as usual. If the 
> fields are missing, then the serialized form was from the old class, 
> in this case copy the values from the immutable values in BaseDateTime.
> Note I have not tried this.
> Mark Thornton
An even simpler method would modify MutableDateTime as follows

public class MutableDateTime extends BaseDateTime {
    private long iMillis;
    private Chronology chronology;

    private void readObject(ObjectInputStream in) throws ... {
       iMillis = super.getMillis();
       chronology = super.getChronology();

    public long getMillis() {return iMillis;}
    public Chronology getChronology() {return chronology;}

    // ...

This should be backward compatible with existing serialized instances 
while allowing the fields in BaseDateTime to be final. It comes at the 
expense of a slightly larger MutableDateTime object, and slightly slower 

Mark Thornton

More information about the Concurrency-interest mailing list