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
。为什么编译器不能检测到这个错误?
原文由 saravanan 发布,翻译遵循 CC BY-SA 4.0 许可协议
通过使用强制转换,你实际上是在告诉编译器“相信我。我是专业人士,我知道我在做什么,而且我知道虽然你不能保证,但我告诉你这
animal
变量肯定是一只狗。”由于动物实际上不是狗(它是动物,你可以做
Animal animal = new Dog();
它是一只狗)虚拟机在运行时抛出异常,因为你违反了这种信任(你告诉编译器一切都会好起来的,但事实并非如此!)编译器比盲目接受一切更聪明,如果你尝试在不同的继承层次结构中转换对象(例如将 Dog 转换为 String),那么编译器会把它扔回给你,因为它知道这永远不可能工作。
因为你基本上只是阻止编译器抱怨,所以每次你强制转换时,重要的是检查你不会导致
ClassCastException
通过在 if 语句(或其他东西)中使用instanceof
达到那个效果。)