为什么ClassCastException只发生在运行时



考虑以下代码。

class B {}
class B1 extends B {}
class B2 extends B {}
public class ExtendsTest{
public static void main(String args[]){
B b = new B();
B1 b1 = new B1();
B2 b2 = new B2();
}
}

现在当你做

b1=(B1)b;

它仍然编译,即使很明显b不可能是B1的大小写。所以为什么编译器在这里并没有给出错误。

而是在运行时出现ClassCastException。编译器在这里应该更智能。

这是经过设计的,是动态/运行时多态性的核心概念。

通过编写B b = new B();,您可以做两件事:

1-指示编译器b是对类型B的引用

2-创建B的实例并将其分配给b

在编译时,只检查点-1。实际存储的内容-在运行时检查,而不是在编译时检查这就是运行时多态性的设计方法。我们可以在运行时将BB1B2的实例分配给b

这有助于编写更易于维护的&可扩展代码。

在您的代码b1=(B1)b中,编译器认为b可能具有对象B1、B2或B。编译器有意跳过此项,以便在运行时进行检查。如果你想避免运行时错误,你可以在If块内写你的代码:

if (b instanceof B1){
b1=(B1)b;
}

这里B类是超类,可以引用到子类(B1类、B2类(的对象

B obj1 = new B1();

B obj2 = new B2();

现在,如果您创建引用类型为B1的对象,指向B的对象(父类(,这将不起作用,除非您用父类强制转换obj1,因为B1 B1不知道父类(B(指向B1。

B1 b1 = obj1; //error
B1 b1 = (B)obj1; //error

现在,在您的情况下,父类没有指向子类B b = new B();,但当您强制转换b1=(B1)b;时,它认为b可能指向子类,因此它最初不会显示任何错误,但在编译时会显示错误。

(我不完全确定我说了什么,但我认为这是有道理的(

因为Java类是在运行时构建和实现的,所以它们与其他类和接口的关系就会建立起来。因此,Java在运行时会注意到与类B1相关的逻辑错误!JVM负责在编译时检查语法错误。JVM在编译时无法检测到类似这样的错误,因为Java编译器尚未创建类及其与其他组件的关系。祝好运

最新更新