On 03/12/2015 09:49 PM, Alan Bateman wrote:
On 05/03/2015 13:46, Chris Hegarty wrote:
:
Example:
class Stamp implements Serializable {
private transient final long millis;
Stamp() { millis = System.currentTimeMillis(); }
public long stamp() { return millis; }
private void readObject(java.io.ObjectInputStream in) throws
Exception {
in.fields().set("millis", System.currentTimeMillis());
}
}
We have a fully working implementation, tests, etc, in the sandbox:
hg clone http://hg.openjdk.java.net/jdk9/sandbox sandbox
cd sandbox
sh get_source.sh
sh common/bin/hgforest.sh update -r serial-exp-branch
Webrev for convenience:
http://cr.openjdk.java.net/~chegar/8071472/00/webrev/
Hi Alan,
I've spent some time looking at this and trying it out. It's very
simple, doesn't impact any existing readObject implementations, and
provides a way to set final fields without restoring to Unsafe.
That was the plan. :-)
So if a readObject calls fields() without calling defaultReadObject()
then it has to set every final field. On one hand that ensures that
every final field is set, on the other hand it is a bit odd because
omitting the call to fields() means they all get their default value.
If fields() is not called, we must be backwards-compatible.
But yes, this constraint is questionable. On one hand it tries to mimic
the assignment to final fields in constructors, but it can't go all the
way, as read access to final fields in readObject() is not limited to
just those that have already been assigned (like it is in constructor
with definitive assignment rules). We could add get() methods to
FieldAccess that would constraint the reads of final fields to those
that have already been assigned, but that is just like "advisory
locking" - we can only advise users to use FieldAccess to read fields in
readObject() but we can't prevent them from reading them directly.
So if this doesn't have much sense and brings confusion, it can go away.
I think serialization types with final fields that aren't in the
serialized form will really like this. To help developers then it
might be useful to put an example in the javadoc with final &&
transient field to show the usage.
One other thing is naming as OIS.FieldAccess in the current patch
hints that it provides general access. It feels like it should be
something like ObjectFieldSetter with fields() changing to something
like fieldSetter() to make that clearer too.
Or just ObjectInputStream.FieldSetter (like it is now an inner
interface) and fieldSetter() for method. I agree, it sounds better.
Regards, Peter
-Alan.