On 01/08/2015 02:10 PM, Brian Goetz wrote:
1) Validate invariants
A clear and easy to understand mechanism that can validate the
deserialized
fields. Does not prevent the use of final fields, as the
serialization framework
will be responsible for setting them. Something along the lines
of what David
suggested:
private static void validate(GetField fields) {
if (fields.getInt("lo") > fields.getInt("hi")) { ... }
}
This could be a “special” method, or annotation driven. TBD.
Note: the validate method is static, so the object instance is
not required to
be created before running the validation.
Sort of...
This is true if the fields participating in the invariant are
primitives. But if they're refs, what do you do? What if you want to
validate something like
count == list.size() // fields are int count, List list
? Then wouldn't GetField.getObject have to deserialize the object
referred to by that field?
In fact you cannot validate invariants across multiple objects at all
using this method *or* readObject() (existing or enhanced) unless the
object in question is an enum, Class, or String (and a few other special
cases) because you can't rely on initialization order during
deserialization. That's the very reason why OIS#registerValidation()
even exists - inter-object validation is not possible until after the
root-most readObject has completed, which is the time when validations
are executed. Robust validation of a given object class may require two
stages - "near" validation and "spanning" validation - to fully
validate. However the readObject() approach and its proposed variations
(including the static validate() version) can still be useful for
fail-fast and non-complex validations; you just have to understand that
(just as today) any Object you examine might not be fully initialized yet.
--
- DML