我对以下代码无效并抛出ClassCastException有点困惑:
Person superPerson = new Person("marc", 18);
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
System.out.println(subPerson);
子类与super:
相同public class PersonOverwritten extends Person {
public PersonOverwritten(String nome, int idade) {
super();
}
}
当然,如果它们来自不同的类型,它应该会失败,但是,为什么这不起作用?
答案 0 :(得分:2)
这是一个简单的例子来说明。想象一下,PersonOverwritten
看起来像这样:
public class PersonOverwritten extends Person {
public PersonOverwritten(String nome, int idade) {
super();
}
public void pickupSticks() {}
}
很明显你无法做到
Person superPerson = new Person("marc", 18);
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
subPerson.pickupSticks();
因为分配给subPerson
的对象没有pickupSticks
方法。
编译器允许你编写这样的代码的原因是,你有一天可能想做这样的事情:
Person person = new PersonOverwritten("marc", 18);
((PersonOverwritten)person).pickupSticks();
在这种情况下,当然不会出现运行时错误,因为您分配给person
的对象支持扩展接口。看到类似内容的一个非常常见的地方是在Java 1.5中引入泛型之前,当您访问它们时,所有集合都返回Object
。
<强>更新强>
为了详细说明,Java使用类型来确定对象实现的契约,而不是直接检查属性。它不使用duck-typing,比如说Python。编译器允许您将Person
转换为PersonOverwritten
,因为可能可能。运行时将禁止您使用实际的Person
对象作为PersonOverwritten
,因为根据Java,它不符合接口。
答案 1 :(得分:1)
您无法将new Person()
投射到PersonOverwritten
。
虽然编译器将允许此传递,但运行时将检测到类型Person
太宽而不适合PersonOverwritten
,这就是为什么你得到ClassCastException
。
只是旁注:如果你有一个不同的,无关的同一父类的子类,会发生类似的异常:
public class AnotherPersonOverwritten extends Person {}
以下内容也不正确:
Person subPerson = new AnotherPersonOverwritten();
PersonOverwritten personOverwritten = (PersonOverwritten) new subPerson;
//class cast exception
如何避免这种情况:确保正在投射的对象的运行时类(在这种情况下使用new
关键字的类)与或者对象被投射到的类的子类。
答案 2 :(得分:0)
将父类的对象分配给其子类引用变量将失败。在评论中提及#Turing85 和 #rgettman 。
请查看以下代码:
Dog dog = new Dog();
// Cat cat = new Cat();
// Animal animal = cat;
Animal animal = dog; // here upcasting is automatic
if(animal instanceof Dog) // only if the animal is of type Dog
Dog dogDup = (Dog) animal; // manual downcasting
/*
Animal animal = new Animal();
Dog dog = (Dog) animal; // this won't work
*/
请参阅完整文章here
为了防止代码抛出运行时异常,请像这样使用instanceof运算符
Person superPerson = new Person("marc", 18);
if(superPerson instanceof PersonOverwritten) // in this case it's "false"
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
[有关详细信息,请参阅this stackoverflow问题]
希望这会有所帮助!