当一个子类等于超类

时间:2018-04-17 16:59:42

标签: java casting classcastexception

我对以下代码无效并抛出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();
    }

}

当然,如果它们来自不同的类型,它应该会失败,但是,为什么这不起作用?

3 个答案:

答案 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问题]

希望这会有所帮助!