Possible Java code transformation to implement the "reasonable semantics"

Up, Top, Middle, Bottom classes are unchanged
Transforation localized in Down class (essential for incremental compilation).
Client and results

Original version; naive translation of the model into Java.



public class U {
    public void cv(T t) {//covariance
        System.out.println("cv(T) in U ");
    }
    public void ctv(B t) {// contravariance
        System.out.println("ctv(B) in U ");
    }
    public void inv(M m) {// invariance
        System.out.println("inv(M) in U ");
    }
}

public class T {
}


public class M extends T {
}


public class B extends M {
}


public class D extends U {
    public void cv(M m) {//covariance
        System.out.println("cv(M) in D");
    }
    /*
    * added code to simulate the covariant behavior in column 3
    * "correct" the yellow differences of the Java Table.
    */
    public void cv(T m) {//redefinition to simulate the "reasonable" lookup : slot (2,3) and (3,3)
        try {
            if (m.getClass() == Class.forName("T")) {// Dynamic type not static one, so...
                super.cv(m);
            } else {
                cv((M) m);
            }
        }
        catch(ClassNotFoundException e) {//never}
        }
    }

    public void ctv(M m) {// contravariance
        System.out.println("ctv(M) in D");
    }
    /*
    * added code to supress the ambiguity of slot (6,2)
    * "correct" the blue difference of the Java Table.
    */
    public void ctv(B b) {//redefinition to force the choice slot(6,3)
        ctv((M) b);
    }

    public void inv(M m) {// invariance
        System.out.println("inv(M) in D ");
    }
}



public class TestCoCon {

    public static void main(String [] ar) {

        U u = new U();
        D d = new D();
        U w = new D();

        T t = new T();
        M m = new M();
        B b = new B();

        System.out.println("-- first test suite");
        u.cv(t);
        u.cv(m);
        u.cv(b);
        //u.ctv(t);
        System.out.println("ctv(B) in U cannot be applied to (T)");
        //u.ctv(m);
        System.out.println("ctv(B) in U cannot be applied to (M)");
        u.ctv(b);
        //u.inv(t);
        u.inv(m);
        u.inv(b);
        System.out.println("-- second test suite");
        d.cv(t);
        d.cv(m);
        d.cv(b);
        //d.ctv(t);
        System.out.println("cannot resolve symbol");
        d.ctv(m);
        d.ctv(b);
        //System.out.println("reference to ctv is ambiguous, both method ctv(B) in U and method ctv(M) in D match");
        //d.inv(t);
        d.inv(m);
        d.inv(b);
        System.out.println("-- third test suite");
        w.cv(t);
        w.cv(m);
        w.cv(b);
        //w.ctv(t);
        System.out.println("ctv(B) in U cannot be applied to (T)");
        //w.ctv(m);
        System.out.println("ctv(B) in U cannot be applied to (M)");
        w.ctv(b);
        //w.inv(t);
        w.inv(m);
        w.inv(b);
    }
}


Results as expected by the "reasonable" semantics

-- first test suite
cv(T) in U
cv(T) in U
cv(T) in U
ctv(B) in U cannot be applied to (T)
ctv(B) in U cannot be applied to (M)
ctv(B) in U
inv(M) in U
inv(M) in U
-- second test suite
cv(T) in U
cv(M) in D
cv(M) in D
cannot resolve symbol
ctv(M) in D
ctv(M) in D
inv(M) in D
inv(M) in D
-- third test suite
cv(T) in U
cv(M) in D
cv(M) in D
ctv(B) in U cannot be applied to (T)
ctv(B) in U cannot be applied to (M)
ctv(M) in D
inv(M) in D
inv(M) in D