public class CovariantTest {
public A getObj() {
return new A();
}
public static void main(String[] args) {
CovariantTest c = new SubCov
c is typed as CovariantTest at compile time and thus the call to c.getObj() is bound to the method CovariantTest.getObj() at compile time (and that can't be modified at runtime).
Also, x exists in both A and B (it is shadowed, not overridden). Because the method being called is CovariantTest.getObj() and that method works with A, the x being retrieved is A.x even though the actual object is of type B.