So,
any instance of B is also an instance of A, and
any instance of D is also an instance of A, and
any instance of C is also an instance of B, and
any instance of C is also an instance of A.
According to the
Java Language Specification, "the result of the instanceof operator is true if the value of the ... [first operand, which must be a reference] is
not null and the reference could be cast (�15.16) to the ... [second operand, which must be a type] without raising a ClassCastException. Otherwise the result is false." (The bold is mine.)
"a1 = new D()" creates a new instance of type D, and assigns it to a variable of type A (an upcast). So, "(a1 = new D()) instanceof C" returns false, because the true runtime type of a1 is D, and an instance of D is
not an instance of C. In particular, a reference to an instance of D cannot be cast to type C without a ClassCastException.
Now,
here's the trick: Because this evaluates to false, the second boolean is not evaluated due to short-circuiting of the && operator. In particular, "a2 = new B()" does
not execute, and
a2 remains a null reference. Therefore, "a2 instance of B" actually returns false.
Ref:
http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#80289 [ August 23, 2005: Message edited by: marc weber ]