The Java Memory Model, as reworked for Tiger,
gives preferential treatment to final fields.
In particular, immutable objects with final fields do not need synchronization.
However, how does one deserialize such objects, if the final field must be
assigned to in the deserialization method?
In the JDK, we can work around this thus:
(from CopyOnWriteArrayList.java)
// Support for resetting lock while deserializing
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final long lockOffset;
static {
try {
lockOffset = unsafe.objectFieldOffset
(CopyOnWriteArrayList.class.getDeclaredField("lock"));
} catch (Exception ex) { throw new Error(ex); }
}
private void resetLock() {
unsafe.putObjectVolatile(this, lockOffset, new ReentrantLock());
}
but.... this technique is strange, not very well known, and uses
JDK internal mechanisms. What are 3rd party class authors to do?
Brian Goetz writes:
"Can we explore ways to fix this for Dolphin, even if it does require
proposing language changes? Final got so much more important in Tiger,
that the requirement to choose between using final and using
serialization is really an unfair choice to present user with. Telling
the user base "we can write immutable serializable classes, but you
can't" is just mean."