考虑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接口的参考。最好的问候
答案 0 :(得分:2)
只有在转换对象确实扩展此类或实现此接口时,才能将对象转换为给定的类或接口。如果没有(即如果对象不是类或接口的实例),则会得到ClassCastException。注意,将对象强制转换为类并不会更改对象的类型。它只允许将它作为另一种类型引用,它也是,扩展或实现。
让我们看看你的例子:
a = (B)(I) b;
首先会转换对象b
,其类型为B
。到界面I
。这是正常的,因为B扩展了A,而A实现了I,这意味着B也实现了I.
然后它第二次将同一个对象强制转换为类B
。 b
是B
的一个实例,因此可行。
I i = (C) a;
这会将类型a
的对象A
强制转换为类C
。 A不会扩展C,所以这是不可能的。
答案 1 :(得分:0)
在Java中转换引用类型只是程序员的自检符号。这些类型的变量只包含对象的引用(指针)。在铸造期间既不参考本身,也不参考对象的变化。实际上这样的铸造什么都不做。
只有在将宽型变量分配给窄型变量时才需要进行自检。例如,从超类到子类。因为错误只能在这里。从等类型变量或较窄类型分配时,不需要检查,因为它总是可行的。