(new A()).m1() = 1 (new A()).m2() = 1 (new A()).m3() - ill-typed (new A()).m4() - ill-typed (new B()).m1() = 2 (new B()).m2() = 2 (new B()).m3() - ill-typed (new B()).m4() - ill-typed (new C()).m1() = 2 (new C()).m2() = 2 (new C()).m3() = 2 (new C()).m4() = 2 (new D()).m1() = 3 (new D()).m2() = 3 (new D()).m3() = 3 (new D()).m4() = 2 int i1 = (new A()).m1() + 5; // yes/yes A a = new A(); // no/no; m3 does not exist in A int i2 = a.m3(); C c = new C(); // yes/yes int i3 = ((A)c).m1(); B b1 = new C(); // no/yes; m3 does not exist in B which is int i4 = b1.m3(); // the static type of b1 B b2 = (A)(new C()); // no/yes; a reference to B cannot be // assigned a value of type A since A // is not a subtype (subclass) of // B. The static type of the // expression (A)(new C()) is A, while // the actual type at run time is C // therefore this fragment can be run // error free. B b3 = (C)(new A()); // yes/no; The run time cast check fails // since A is not a subtype of C. class M { // no/no; The method p is expected to return Integer p() { // an Integer, but the type of the expression return (new C()).m4(); // (new C()).m4() is int instead. } } C[] ca = new C[3]; // yes/no; The implicit check inserted by Java // will raise an exception in the B[] ba = ca; // ba[0] = ... line. The reason: the object ba[0] = new B(); // being assigned is of type B while the actual A[] aa = ba; // array type is C[] and B is not a subtype of C. int i5 = (aa[0]).m1(); C[] ca1 = (C[])(new A[3]); // yes/no; Both casts cannot be satisfied. ca1[0] = (C)(new A());