考虑以下简单代码:
class A {}
class B extends A {}
public class TestClass {
public static void main(String args[]) {
A[] a, a1;
B[] b;
a = new A[10];
a1 = a;
b = new B[20];
a = b; // 1
b = (B[]) a; // 2
b = (B[]) a1; // 3
}
}
仔细看看我在1,2和3处注释过的行。由于从子类引用到超类引用进行了赋值,因此在编译期间将允许使用第1行。
需要在第2行进行强制转换,因为将超类引用分配给了子类引用变量。这在运行时有效,因为a引用的对象实际上是B数组(第1行)。
现在,这就是我的困惑所在:第3行将抛出java.lang.ClassCastException。现在,这意味着在运行时,程序意识到实际对象不是B的数组,而是A的数组。
这正是我不理解的。 B不会扩展A吗?所以它满足条件B IS-A A,对吗?因此,第3行在运行时是否不应抛出任何异常?
最佳答案
a1
是A
元素的数组。由于B
扩展了A
,因此B
的所有实例也是A
的实例,但并非所有A
的实例都是B
的实例。您可以定义一个类C
,它也扩展了A
并将该类的实例分配给a1
数组。这样的实例不是B
的实例。
因此,您不能将A
元素数组转换为B
元素数组。