繁体   English   中英

在转换子类等于超类时,强制转换失败

[英]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。 编译器允许您将PersonPersonOverwritten因为它可能是可能的。 运行时将禁止您将实际的Person对象用作PersonOverwritten因为根据Java,它不支持接口。

您不能将new Person() PersonOverwrittenPersonOverwritten

虽然编译器会让这个传递,但是运行时会检测到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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM