2017-02-13 6 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); 

Это дает ошибку компиляции.

Несоответствие типа: не может конвертировать из Integer в SampleTester.A2

как я это вижу, A2 не связан с А1 каким-либо образом (точно так, как целое не имеет отношения), так как Приходите бросить работу?

ответ

6

Прежде всего, заголовок вашего вопроса неверен - вы не выполняете двух классов - вы производите выражение, тип которого является типом интерфейса для типа класса.

test.get(0) имеет тип A1, интерфейс. Несмотря на то, что A2 не реализует этот интерфейс, некоторый подкласс класса A2 может реализовать интерфейс (и на самом деле вы определили такой класс - A3), поэтому приведение может быть успешным. Поэтому компилятор допускает это.

Integer не может быть подклассифицирован (это конечный класс), поэтому никогда не будет подкласса Integer, который реализует A1. Поскольку приведение не может быть успешным, компилятор не разрешает это делать.

+1

отличный ответ, спасибо. после вашего ответа я понял, что даже после принятия «extends A2» он компилируется, что означает (исправьте меня, если я ошибаюсь), компилятору не нужно видеть истинное соединение иерархии, просто потенциал одного. – DsCpp

+0

@DsCpp Это правильно. – Eran