2017-02-13 48 views
3

我想了解java编译器如何工作有关类型铸造,但我无法弄清楚。两个大概不相关的类之间的Java铸造

,请参见下面的代码

public class SampleTester{ 
    public static interface A1{} 
    public static class A2{} 
    public static class A3 extends A2 implements A1{ 
     public static void main(String[] args){ 
      List<A1> test = new ArrayList<>(); 
      test.add(new A3()); 
      A2 a2 = (A2) test.get(0); 
     } 
    } 
} 

这段代码编译,但如果我改变

A2 a2 = (A2) test.get(0); 

A2 a2 = (Integer) test.get(0); 

它提供了编译错误。

类型不匹配:因为我看到它不能从整数转换到SampleTester.A2

,A2是不相关的A1以任何方式(完全按整数是没有关系的),因此如何投来的作品?

回答

6

首先,您的问题的标题不正确 - 您不是在两个类之间进行投射 - 您正在将类型为接口类型的表达式转换为类类型。

test.get(0)A1类型的接口。尽管A2没有实现该接口,但某些A2的子类可能会实现该接口(并且实际上您已定义了这样的类 - A3),因此该转换可以成功。因此编译器允许它。

Integer不能被分类(这是最后一类),所以不会有Integer的子类实现A1。由于转换不能成功,编译器不允许它。

+1

很好的答案,谢谢。在你回答之后,我意识到,即使在采用“扩展A2”之后,它也会编译,意思是(如果我错了,就纠正我),编译器不需要看到真正的层次结构连接,只是潜在的一个。 – DsCpp

+0

@DsCpp这是正确的。 – Eran