给定以下代码,我有一个问题:
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
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是粗体字。我的理解是,对于要编译的代码,只需要满足这些类在相同的层次结构中,并因此可以工作(在树上进行隐式强制转换,在树上进行显式强制转换)即可。每当我遇到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)。