为什么在这种情况下向下转换会抛出ClassCastException?

时间:2018-10-22 15:02:25

标签: java casting downcast upcasting

我有2个软件包:控制器和联合身份验证。控制器仅包含具有main方法的控制器类,但联合身份验证包含2个类,Shuttle(父类)和MiniShuttle(子类)。向上转换的工作原理很吸引人,但是当我尝试向下转换时,会收到ClassCastException。

这是我尝试的代码:

Shuttle.java

package federation;

public class Shuttle {

    protected int passengers;

}

MiniShuttle.java

package federation;

public class MiniShuttle extends Shuttle {


}

Controller.java

package controller;

import federation.MiniShuttle;
import federation.Shuttle;

public class Controller {

    public static void main(String[] args) {
        Shuttle shuttle = new Shuttle();
        MiniShuttle mshuttle = (MiniShuttle)shuttle;

        if(mshuttle instanceof Shuttle)
        {
            System.out.println("ok");
        }else
        {
            System.out.println("not ok");
        }

    }

}

4 个答案:

答案 0 :(得分:3)

因为您已实例化Shuttle。声明new Shuttle()表示实例化类型为Shuttle的对象,对该对象的引用为Shuttle(来自Shuttle shuttle = ...)。 如果要使其正常工作,请使用Shuttle shuttle = new MiniShuttle()。这样,您实际上是在说“我正在实例化一个MiniShuttle类型的对象,并将对该对象的引用上载为Shuttle类型的对象。”

答案 1 :(得分:2)

正如您所说,您正在铸造,这意味着要从父辈投射到孩子-因为shuttle的类型为Shuttle并且不是MiniShuttle

您可以用另一种方法来做

MiniShuttle miniShuttle = new MiniShuttle();
Shuttle shuttle = (Shuttle) miniShuttle;

这样,您就可以进行广播了,这非常好,因为每个MiniShuttle也是Shuttle

答案 2 :(得分:0)

OOPS中的合同是由超级类而不是子类定义的。 基本上,扩展合同被定义为“是”关系,其中子类是父类的对象,反之亦然

以这种方式阅读,MiniShuttle是Shuttle,但Shuttle不是MiniShuttle

答案 3 :(得分:0)

您在main方法的第1行中将“ shuttle”实例化为通用Shuttle对象,但随后尝试将其强制转换为MiniShuttle。您不能这样做,因为Shuttle不一定是MiniShuttle,而是其他东西。这是另一个示例,希望可以更清楚地说明为什么这将是一个错误的假设,而更具体的示例将说明为什么这是一个错误的假设。

form = u'{:<{width}}\t{:<3}({})'
for line in a:
    line = line[:12]
    adjust = len(line) - malayalam_width(line)
    print form.format(line, 1, 2, width=12 + adjust)

FerengiShuttle是一种穿梭,而mshuttle也是一种穿梭,但是ssQuark并不是MiniShuttle,也从未打算这样做。如果您有通用的Shuttle对象,则无法进行向下转换所需的必要假设。