Будучи абсолютно строгим, это не скомпилируется, потому что в строке 4 вы набираете Class
вместо class
Class D extends C{}
И позже вы определяете дважды a
и 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
Теперь, предполагая, что это были опечатки, результат будет ClassCastException
, потому что c
не может быть приведен к E
.
Когда вы выполняете приведение типа, вы говорили: «Я программист, и я знаю, что это ...» ____(put your class here)
И компилятор позволит вам скомпилировать.
Но если в время выполнения экземпляр на самом деле не является ____ (E
в данном случае, а это не так), то он выдаст ClassCastException
.
Программа не выйдет из строя с A a = ( B ) c
; потому что c
является экземпляром C
, который является подклассом B
.
Можно сказать, что C
- это a B
. Чтобы понять это лучше подумайте над следующей декларацией:
class Employee extends Object {
}
Каждый Employee
является Object
, поэтому приведение будет успешным, на самом деле, настолько ясно, что оно выполнится, что вам даже не нужно ставить оператор приведения ()
.
Employee e = new Employee();
Object o = ( Object ) e; // or much better:
Object o2 = e; // no cast needed when assigning to superclass.
Но не обязательно Object
- это Employee
.
Object o = ....
Employee e = ( Employee ) o; // will fail if o was not created as an Employee.
Вот почему A a = ( E ) c;
терпит неудачу, потому что ссылка c
была , а не , созданная как E
Надеюсь, это поможет.