Agreed, the solution below works in the use case I gave (and thats
what I'm using as a workaround). However, its not optimal, which is
why I raised the (broader) question here.

(This solution doesn't allow me to use readObject/writeObject to
actually control the wire bits, such as to flatten the Duration and
PeriodField to their constituent parts. Thats part of the broader
problem of controlling the serialized form of an immutable class,
without needing an inner proxy class.)

On 31 January 2010 04:04, Goktug Gokdogan <gokdo...@gmail.com> wrote:
> I would put the first element to a different field, make periods field
> transient and implement a readResolve method that calls a constructor.
>
> So, something like this should solve your problem easily, right?
>
>  private final String name
>  private final Duration duration
>  private final PeriodField firstPeriod
>  private final transient List<PeriodField> periods
>  private final transient int hashCode
>  private Object readResolve() throws java.io.ObjectStreamException {
>     return new MyImmutableClass(name, duration, firstPeriod); //you can
> define a private constructor if required
>  }
> On Sat, Jan 30, 2010 at 7:44 PM, Stephen Colebourne <scolebou...@joda.org>
> wrote:
>>
>> I thought I'd raise an issue with serialization that I've had a problem
>> with more than once. Perhaps there is an obvious easy solution, but I can't
>> see it (I can see hard workarounds...)
>>
>> In JSR-310 we have lots of immutable classes. One of these stores four
>> fields:
>>
>>  private final String name
>>  private final Duration duration
>>  private final List<PeriodField> periods
>>  private final int hashCode
>>
>> For serialization, I only need to store the name, duration and element
>> zero from the periods list. (The rest of the period list is a cache derived
>> from the first element. Similarly, I want to cache the hash code in the
>> constructor as this could be performance critical.). Storing just these
>> fields can be done easily using writeObject()
>>
>> But, when you implement readObject(), you cannot store the read values
>> into the fields because they are final. Nor can I stash them somewhere ready
>> for readResolve().
>>
>> From my perspective, what I need is a combined readObject() and
>> readResolve():
>>
>>  private Object readObjectAndResolve()
>>
>> I could then read the stream, and call the constructor to properly
>> initialise the object state (including the full period list and hash code
>> caches). This seems to be a general problem with deserializing immutable
>> classes.
>>
>> Workarounds include lazily creating the caches in transient fields,
>> bloating the serialzed data, using reflection or creating a dummy inner
>> class to act as the serialized form. All are rubbish solutions.
>>
>> Any suggestions? And if not, what about adding the suggested method to the
>> JDK?
>>
>> Stephen
>>
>
>

Reply via email to