[英]Cast fails when casting a sub class equals to the super class
我有点混淆为什么下面的代码不起作用并抛出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();
}
}
当然,如果它们来自不同类型,它应该会失败,但是,为什么这不起作用?
这是一个简单的例子来说明。 想象一下, 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,它不支持接口。
您不能将new Person()
PersonOverwritten
为PersonOverwritten
。
虽然编译器会让这个传递,但是运行时会检测到Person
类型太宽PersonOverwritten
适合PersonOverwritten
,这就是你得到ClassCastException
。
只是旁注:如果您拥有同一父级的不同,不相关的子类,则会发生类似的异常:
public class AnotherPersonOverwritten extends Person {}
以下内容也不正确:
Person subPerson = new AnotherPersonOverwritten();
PersonOverwritten personOverwritten = (PersonOverwritten) new subPerson;
//class cast exception
如何避免这种情况 :确保要转换的对象的运行时类(在这种情况下使用new
关键字的类)与要转换对象的类的子类相同。
将父类的对象分配给其子类引用变量将失败。 正如#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
*/
请参阅此处的完整文章
要防止代码抛出运行时异常,请像这样使用instanceof运算符
Person superPerson = new Person("marc", 18);
if(superPerson instanceof PersonOverwritten) // in this case it's "false"
PersonOverwritten subPerson = (PersonOverwritten) superPerson;
[有关详细信息,请参阅此 stackoverflow问题]
希望这会有所帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.