小编典典

从超类到子类的显式转换

all

public class Animal {
    public void eat() {}
}

public class Dog extends Animal {
    public void eat() {}

    public void main(String[] args) {
        Animal animal = new Animal();
        Dog dog = (Dog) animal;
    }
}

赋值Dog dog = (Dog) animal;不会生成编译错误,但在运行时会生成ClassCastException.
为什么编译器不能检测到这个错误?


阅读 81

收藏
2022-08-20

共1个答案

小编典典

通过使用强制转换,您实际上是在告诉编译器“相信我。我是专业人士,我知道自己在做什么,而且我知道虽然您不能保证,但我告诉您这个animal变量绝对是会变成一条狗。”

由于动物实际上不是一只狗(它是一只动物,你可以这样做Animal animal = new Dog();并且它会是一只狗)VM
在运行时抛出一个异常,因为你违反了这种信任(你告诉编译器一切都会好起来的,它是不是!)

编译器比盲目地接受所有东西要聪明一点,如果您尝试将对象转换为不同的继承层次结构(例如将 Dog 转换为
String),那么编译器会将其扔回给您,因为它知道这永远不可能工作。

因为您实际上只是在阻止编译器抱怨,所以每次转换时,重要的是检查您不会在 if
语句中ClassCastException使用instanceof(或类似的东西)。

2022-08-20