Being completely strict, that' won't compile because in line 4 you type Class instead of class
Class D extends C{}
And later you define twice a and c
C c = new C(); // once
B b = c;
A a = (E)c; // once a
A a = (B)c; // twice c
C c = (C)(B)c; // twice
Now assuming those were typos the output would be ClassCastException because c can't be casted to E.
When you perform a cast is like you were saying: "I'm the programmer and I know this is a..." ____(put your class here) And the compiler will allow you compile.
But if in runtime the instance is not really a __ ( an E in this case, which is not ) then it will throw ClassCastException.
The program won't fail with A a = ( B ) c; because c is an instance of C which is a subclass of B.
You can say that, C is a B. To understand it better think on the following declaration:
class Employee extends Object {
}
Every Employee is an Object so the cast will succeed, actually is it so clear that it will succeed that you don't even need to put the cast operator ().
Employee e = new Employee();
Object o = ( Object ) e; // or much better:
Object o2 = e; // no cast needed when assigning to superclass.
But not necessarily an Object is an Employee.
Object o = ....
Employee e = ( Employee ) o; // will fail if o was not created as an Employee.
That's why A a = ( E ) c; fail, because, the reference c was not created as an E
I hope that helps.