给定以下代码,我有一个问题:
class A{} class B extends A {} class C extends B{} public class Test { public static void main(String[] args) { A a = new A(); A a1=new A(); B b = new B(); // a=b;// ok // b=(B)a;// ClassCastException // a=(A)a1; // ok // a=a1; // ok a=(B)a1; // compiles ok, ClassCastException } }
我的问题是粗体字。我的理解是,对于要编译的代码,只需要满足这些类处于相同的层次结构中,并因此可以起作用即可(在树上隐式强制转换,在树上隐式强制转换)。每当我遇到ClassCastException时,是因为引用指向树上的一个对象,例如,指向B类型的对象的B类型的引用。
问题所在的行似乎是指向类型A的对象的类型A的引用。强制转换为(B)显然是导致ClassCastException的原因。有人可以解释一下如何做到这一点吗?
注意:如果a1指向B类型的对象,则它可以工作(刚刚对其进行了测试)。因此,对于编译器,向下转换是合法的,并且如果引用指向正确类型的对象,则可以毫无例外地执行该向下转换。
通过将A ref a1强制转换为B并将其分配给a,看来A ref a不再期望引用类型A的对象,而是B?
谢谢,肖恩。
PS我知道这有点不寻常,准备Java认证。通常我们向下转换到左侧的类型,例如b =(B)a; (而且我可以看到为什么给出了ClassCastException)。
通过继承,所有B均为A。但是,并非所有的A都是B。该特定实例不是,因此运行时异常。