Why can't I get a compilation error in the code below?
Because the compiler only cares about the static type of expression that you are trying to execute.
Take a look at these two lines:
BlackInk blackInk = new BlackInk(); printable = (Printable)blackInk;
You know that in the second line, the value blackInk refers only to an object of type blackInk because of the first line, but the compiler does not. For the entire compiler (when compiling the second line), this could be:
BlackInk blackInk = new PrintableBlackInk(); printable = (Printable)blackInk;
... where PrintableBlackInk is a class that extends blackInk and implements Printable . Therefore, it is valid (at compile time) for translation from an expression of type blackInk to Printable . If you create a class blackInk a final , then the compiler knows that it will not work (if the value is not null) and will not be executed at compile time, for example:
error: inconvertible types printable = (Printable)blackInk; ^ required: Printable found: BlackInk
Details for this are in JLS 5.5.1 .
Otherwise, we need to wait for the runtime to see the failure, since the cast is performed at compile time.
source share