为什么我们可以从Super Class转换为类似的子类:
Object o = getStringObject();
String str = (String) o;
然后使用相同的原理将接口DOWN转换为子类型E.G。?
InterfaceType anInterface;
anInterface = (InterfaceType) SubClassVar;
所以示例1都很好,花花公子。我不明白的是,如果一个接口是实现它的类的超类型,那么当我们将类向下转换为接口时,如果在层次结构中接口更高,我们怎么没有ClassCastException呢?我在某个地方看到,通过类和接口进行转换之间存在差异,但当然他们并不想解释原因,所以我保持开放状态。谢谢,Stack!
答案 0 :(得分:2)
从技术上讲,您升级到接口,因为它在层次结构中比该接口的{假定?)实现者SubClassVar
更高。另外,甚至不需要强制转换,因为无论如何都可以根据该接口来讨论接口的实现,而无需使用强制语法。
你可以向下转换接口,就像你对子类一样。这是一个例子:
interface I1 {}
interface I2 extends I1 {}
class I2Impl implements I2 {}
class Main {
public static void main(String[] args) {
I1 test = new I2Impl();
I2 test2 = (I2)test;
I2Impl test3 = (I2Impl) test2;
}
}
答案 1 :(得分:0)
当程序员显式地将一种类型转换为另一种类型时,通常是因为程序员比编译器更了解对象的运行时类型。编译器可以选择允许任何演员表,因为智能程序员这样说。但是,作为Java,编译器将尝试捕获并防止明显的错误。
如果很明显没有任何对象可以同时属于这两种类型,则不允许在两种类型之间进行转换;换句话说,两种类型的交集是空的。例如,我们无法在String
和Integer
之间进行投射;也不是String
和Runnable
。但是,Number
和Runnable
可以互相投射,因为可以想象两种类型中都可能存在对象。
此外,如果A和B可以相互投射,则只允许进行身份比较a==b
,理由相同。如果编译器知道它们不能是同一个对象,则不允许==
。见JLS
确切的算法非常复杂 - http://docs.oracle.com/javase/specs/jls/se8/html/jls-5.html#jls-5.5.1注意算法是对称的 - 当且仅当B可以转换为A时,A可以转换为B.规范的文本不是很好,可能包含错误(请参阅此question)
“向下转换”是指目标类型是子类型; “upcast”是指目标类型是超类型。通常不需要向上转换,但在需要时会有cases。