Java中向下转换类与向下转换接口的区别?

时间:2015-11-04 17:37:56

标签: java android interface casting

为什么我们可以从Super Class转换为类似的子类:

Object o = getStringObject();
String str = (String) o;

然后使用相同的原理将接口DOWN转换为子类型E.G。?

InterfaceType anInterface;
anInterface = (InterfaceType) SubClassVar;

所以示例1都很好,花花公子。我不明白的是,如果一个接口是实现它的类的超类型,那么当我们将类向下转换为接口时,如果在层次结构中接口更高,我们怎么没有ClassCastException呢?我在某个地方看到,通过类和接口进行转换之间存在差异,但当然他们并不想解释原因,所以我保持开放状态。谢谢,Stack!

2 个答案:

答案 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,编译器将尝试捕获并防止明显的错误。

如果很明显没有任何对象可以同时属于这两种类型,则不允许在两种类型之间进行转换;换句话说,两种类型的交集是空的。例如,我们无法在StringInteger之间进行投射;也不是StringRunnable。但是,NumberRunnable可以互相投射,因为可以想象两种类型中都可能存在对象。

此外,如果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