繁体   English   中英

为什么我在这种情况下得到ClassCastException

[英]why i am getting ClassCastException in this case

请告诉我为什么我在这种情况下得到ClassCastException

我有类型转换类型,B类的源代码如下所示,但为什么我仍然在这里得到ClassCastException。

public class A extends B 
{


}

public class B {
    public String getData() {
        return "B";
    }
}


public class Main {
    public static void main(String args[]) {
        A a = new A();
        B b = new B();
        a = (A) b;
        System.out.println(a.getData());
    }
}

如果我们使用不同的类名,它会变得更加明显:

public class Car extends SomethingWithWheels {}    // was A extends B
public class SomethingWithWheels {}                // was B

public class Train extends SomethingWithWheels {}  // aahh, some C extends B

现在,让我们再次施放:

SomethingWithWheels somethingWithWheels = getItFromSomewhere();
Car car = (Car) somethingWithWheels;

编译器必须抱怨,因为somethingWithWheelsB )可能是一个Train实例( C ),它不能被转换为CarA )。

因为B的实例不是 A的实例。 这真的很简单。

如果你创建一个A的实例,它也是一个B - 因为这就是子类的含义。 但是,如果您创建B的实例,那不是 A ,并且不能像这样分配/强制转换。

您可以强制转换的唯一时间是对象的运行时类是否与您尝试强制转换的类型兼容。 你不能改变现有对象的类 - 这是我认为你可能试图在这里做的 - 只告诉编译器“看,我知道它真的更具体”。

因此,作为反例,以下方法可行:

public static void main(String args[]) {
    B b = new A();
    A a = (A) b;
    System.out.println(a.getData());
}

在这种情况下,变量b被声明为保持对B的引用。 事实证明,您使用A的实例填充它,但对于程序的其余部分,编译器不允许假设bA ,因为它不能保证。 由于您知道在特定情况下它是A ,因此您插入强制转换,这会导致运行时检查对象实际上是A 这个成功,并从这一点上,你可以调用特定的方法A在你的a变量。

但是在这种情况下,根本没有理由进行任何转换 - 在您需要调用的子类上没有可用的额外方法,也没有只采用A而不是B 即使A覆盖了getData以执行不同的操作,如果通过B引用调用,您仍会获得此行为。

您不能将基类强制转换为派生类。 你可以反过来做。

因为您的实例“b”不是A类型(B不扩展A),所以当您将“b”转换为A时它会失败。 相反的方法可行(将类型A的实例转换为类型B)

您正在向下转换并尝试将超类型转换为子类型,这就是为什么它在编译期间表现良好但在运行时因ClassCastException而失败。

你可以打电话:

System.out.println(a.getData());

删除尝试转换类型的行后

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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