Why does line 8 not give a runtime exception? Is it due to the reference 'b' acually referring to a C object?
Look at line 6: 'b' actually holds a 'D' object!
If b contained a C, then this would indeed throw an exception.
A cast never changes the class of an object. You can never cast an object to a type that it does not have. The only time you can cast a supertype to a subtype and have it work properly is if the superclass reference is actually referring to an instance of that particular subtype.