Java Can';t将类强制转换为其子类?

Java Can';t将类强制转换为其子类?,java,casting,Java,Casting,请检查main()方法的最后一行,并将其与上面段落的最后一行进行比较。当我可以将int转换为short时,为什么我不能将引用值转换为它的子类呢 class Mid1Prob1 { public static void main(String[] args) { System.out.println("Testing..."); int x = 3; System.out.println(3); System.out.prin

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

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;
}

您告诉编译器(通过显式转换)相信您没有犯错误,因此它忽略了错误,并且在编译时没有检测到错误。但是当程序运行时,您会得到一个异常,因为
act
Actual
而不是
Sub

有许多类型的转换。在本例中,我们讨论的是(
int
short
)和(父类型到子类型)

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

因为您的
实际
对象不是
Sub
类型,所以它不能用作
Sub
对象

您始终可以从
int
强制转换为
short
,但可能会丢失有关值的信息。 转换按照Java语言规范中的描述进行

有符号整数到整数类型T的缩小转换 只需丢弃除n个最低阶位以外的所有位,其中n是数字 用于表示类型T的位。除了可能的 有关数值大小的信息,这可能会导致 结果值的符号与输入的符号不同 价值观


您不是将int转换为short,而是转换它们,可能会丢失精度。对于对象类型,情况就不同了


通常不能这样做的原因之一是“Sub”可能依赖于“实际”中不存在的字段。

A
short
不是
int
的子类。它们都是存储整数值的完全独立的方式;一个是2字节长,一个是4字节长(通常)。这就是为什么您可以将它们相互转换——将
int
转换为
short
只会忽略
int
的上2个字节。然而,对于另一种情况,您可以考虑具有“是”关系的子类<代码>实际是一个
超级
。而
Sub
是一个
实际的
。但是一个
实际的
并不是一个
,这就是为什么会出现错误。

基本上,你所做的是试图将整数转换成一个对象。这是不可能的。您需要将其转换为超类的对象。

只是一个提示,
short
决不是
int
的子类。强制转换只是对等于
int&0xFFFF
的位值进行重新排列
short
不是
int
的子类型。原语之间没有继承层次结构。实际上,它们不是。它们的名称相同,但
Sub.x
Actual.x
不同
Sub.x
实际隐藏
x
。在
Actual
中,如果要使用
printx()
方法,它将打印
Actual.x
,而不是
Sub.x
,即使实例是
Sub
。无论哪种情况,我的发言都是笼统的。通常不能强制转换为层次结构上低于实际类型的类型。因为这个和其他原因。
(Sub) act