无法将类强制转换为其子类?

时间:2014-03-05 07:00:48

标签: java casting

class Mid1Prob1 {
    public static void main(String[] args) {
        System.out.println("Testing...");
        int x = 3;
        System.out.println(3);
        System.out.println((int) x); // legal to cast primitive value to the same type as itself
        System.out.println((long) x); // legal to cast primitive value to a super type
        System.out.println((short) x); // legal to cast a primitive value to a sub type, but may lose information

        Actual act = new Actual();
        System.out.println(((Actual) act) .x); // legal to cast a reference value to the same class as itself
        System.out.println(((Super) act) .x); // legal to cast a reference value to a superclass of itself, as long as the superclass is actually a superclass of the current class
        System.out.println(((Sub) act) .x); // run-time error, cannot cast a reference value to its subclass
    }
}

class Super {
    public int x = 999;
}

class Actual extends Super {
    public int x = 666; // variables can be public in package-private class
}

class Sub extends Actual {
    public int x = 333;
}

请检查main()方法的最后一行,并将其与上面段落的最后一行进行比较。为什么我不能将引用值转换为它的子类,当我可以将int转换为short?

5 个答案:

答案 0 :(得分:5)

当你这样做时

(Sub) act

你告诉编译器(通过显式强制转换)相信你没有犯错误,所以它忽略了错误并且在编译时间内没有检测到它。但是当程序运行时,你会得到一个例外,因为actActual而不是Sub

答案 1 :(得分:4)

转化种类繁多。在这种情况下,我们讨论的是narrowing primitive conversionintshort)和narrowing reference conversion(父类型到子类型)。

  

为什么我不能将引用值转换为它的子类,但我可以转换为   int to short?

由于您的Actual对象不属于Sub类型,因此无法用作Sub对象。

您始终可以从int投射到short,但可能会丢失有关该值的信息。 转换按Java语言规范

中的描述完成
  

将有符号整数缩小转换为整数类型T.   简单地丢弃除n个最低位之外的所有位,其中n是数字   用于表示类型T的位数。除了可能的丢失   有关数值大小的信息,这可能会导致   结果值的符号与输入符号不同   值。

答案 2 :(得分:2)

short不是int的子类。它们都是存储整合值的完全独立的方式;一个是2个字节长,一个是4个字节长(通常)。这就是为什么你能够将它们相互投射 - 将int强加给short只会忽略int的高2字节。但是,对于另一种情况,您可以考虑具有“is”关系的子类。 Actual SuperSubActual。但Actual不是Sub,这就是您收到错误的原因。

答案 3 :(得分:1)

你没有将int转换为short,你正在转换它们,可能会损失精度。对于对象类型,它是一个不同的故事。

一般来说,你不能做到这一点的原因之一是“Sub”可能依赖于“Actual”中不存在的字段。

答案 4 :(得分:0)

基本上你正在做的是你试图将整数转换为对象。这是不可能的。你需要把它投射到超类的对象中。