On 4/01/2015 9:55 AM, Peter Levart wrote:
----- Original message -----
>
> As Brian points out, this scheme can only validate intra-class
> invariants. It can't validate class-against-subclass state.

Sorry, I meant it can't validate class -against-superclass state.


Did he say that?

Not directly - his example was pointing that out.


Ah, I think you missed my example :), Brian was more or less asking a question, but
the answer is definitely yes.

In my example below, subclass B's constructor creates an unextended instance of A, from within B's static check method. It then uses this copy of A to check A's field against B's. At this point, note an instance of B hasn't been constructed, it can still throw an exception, without B ever being constructed, also you'll note that when an unextended copy of A was constructed, A checked its invariants too. B having satisfied all invariants can now be safely constructed. The unextended copy of A is discarded without ever being shared.


- I don't see how this invariant-checking mechanism can enforce
 invariants between superclass fields and subclass fields.?  For example:

 class A {
    int lower, upper;  // invariant: lower<= upper
 }

 class B extends A {
    int cur;  // invariant: lower<= cur<= upper
 }

 To check such an invariant, the serialization library would have to
 construct the object (in a potentially bad state), invoke the checker at
 each layer, and then fail deserialization if any checker said no.?

Eg, some complexity, but bullet proof:

public class A (

    public final int lower, upper;

     private static boolean check(ReadSerial rs){
        if (rs.getInt("lower")>  rs.getInt("upper"))
             throw new IllegalArgumentException(
                "lower bound must be less than or equal to upper");
       return true;
    }

    public A(ReadSerial rs){
        this(check(rs), rs);
    }

    private A(boolean checked, ReadSerial rs){
        super();
        lower = rs.getInt("lower");
        upper = rs.getInt("upper");
    }

// other constructors omitted must also check invarients
}

class B extends A {

    public final int cur;

    private static ReadSerial check(ReadSerial rs) {
        A a = new A(rs);
        int cur = rs.getInt("cur");
        if ( a.lower>  cur || cur>  a.upper )
             throw new IllegalArgumentException(
                 "cur outside lower and upper bounds");
        return rs;
    }

    public B(ReadSerial rs) {
        super(check(rs));
        cur = rs.getInt("cur");
    }
}

Cheers,

Peter.



On 4/01/2015 9:55 AM, Peter Levart wrote:




Regards, Peter

Reply via email to