为何与父类结构一致的子类强转父类实例会抛出ClassCastException?
为什么父类实例强转成子类会抛出ClassCastException?
嘿,这个问题其实戳中了Java类型系统里一个非常关键的点——对象的实际类型是在运行时确定的,和你用来引用它的变量类型无关。我来一步步给你解释清楚:
核心原因:运行时类型检查
你这段代码里的关键问题出在对象的实际创建逻辑上:
Person superPerson = new Person("marc", 18);
这里new Person(...)创建的是一个纯纯的Person类实例,哪怕你把它赋值给了Person类型的变量,它的本质还是Person对象,和PersonOverwritten没有半毛钱关系。
当你尝试做强制转换时:
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
Java虚拟机在运行时会检查superPerson指向的实际对象类型,发现它是Person,并不是PersonOverwritten(也不是PersonOverwritten的子类),这时候就会直接抛出ClassCastException——毕竟你总不能把一只普通猫,硬当成老虎(猫的子类)来用对吧?本质上它就不是老虎啊。
什么时候强制转换是合法的?
只有当**实际对象的类型是目标子类(或者目标子类的子类)**的时候,强转才会成功。举个正确的例子:
// 实际创建的是子类实例,用父类引用存放 Person superPerson = new PersonOverwritten("marc", 18); // 这时候强转是合法的,因为实际对象就是PersonOverwritten PersonOverwritten subPerson = (PersonOverwritten) superPerson;
这时候JVM检查实际对象类型,发现和目标类型匹配,转换就能顺利完成。
补充:你的子类构造器不影响这个问题
顺便提一句,你写的PersonOverwritten构造器里调用super(),这虽然可能会导致父类的属性没有被正确初始化,但这并不是导致ClassCastException的原因——就算你把构造器改成正确调用super(nome, idade),只要实际对象是Person实例,强转成子类还是会失败。
内容的提问来源于stack exchange,提问作者sylleryum
相关产品推荐
相关产品推荐

