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

时间:2012-02-08 10:46:22

标签: java

请告诉我为什么我在这种情况下得到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());
    }
}

5 个答案:

答案 0 :(得分:2)

如果我们使用不同的类名,那就更明显了:

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),无法转换为Car }(A)。

答案 1 :(得分:0)

因为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而不是{a} {}的方法B。即使A覆盖getData做了不同的事情,如果通过B引用进行调用,您仍会遇到此行为。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

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

您可以致电:

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

删除尝试转换类型的行