显性铸造背后的逻辑

时间:2012-10-12 11:21:38

标签: java inheritance casting

考虑Java中的以下类:

interface I{
}
class A implements I{
}

class B extends A {
}

class C extends B{
}
And the following declarations:
A a = new A();
B b = new B();

一旦你有a = (B)(I) b;代码将编译并运行。并且不明白为什么我需要转换为接口和B类。在我看来,a = b;很好。有人可以向我解释上述显式转换的逻辑,使代码运行良好。

但是一旦你有I i = (C) a;它就会在运行时失败,因为'a'不指向类C的对象。为什么'a'需要指向C类的对象?除此之外,我没有得到进入C类的逻辑。无论如何,你将有I接口的参考。最好的问候

2 个答案:

答案 0 :(得分:2)

只有在转换对象确实扩展此类或实现此接口时,才能将对象转换为给定的类或接口。如果没有(即如果对象不是类或接口的实例),则会得到ClassCastException。注意,将对象强制转换为类并不会更改对象的类型。它只允许将它作为另一种类型引用,它也是,扩展或实现。

让我们看看你的例子:

a = (B)(I) b;

首先会转换对象b,其类型为B。到界面I。这是正常的,因为B扩展了A,而A实现了I,这意味着B也实现了I.

然后它第二次将同一个对象强制转换为类BbB的一个实例,因此可行。

I i = (C) a;

这会将类型a的对象A强制转换为类C。 A不会扩展C,所以这是不可能的。

答案 1 :(得分:0)

在Java中转换引用类型只是程序员的自检符号。这些类型的变量只包含对象的引用(指针)。在铸造期间既不参考本身,也不参考对象的变化。实际上这样的铸造什么都不做。

只有在将宽型变量分配给窄型变量时才需要进行自检。例如,从超类到子类。因为错误只能在这里。从等类型变量或较窄类型分配时,不需要检查,因为它总是可行的。