Подтвердить что ты не робот

Литье в интерфейсе Java Generics

Я наткнулся на ситуацию с кастомной Java, в которой присутствуют общие функции и интерфейсы, которые я не понимаю.

Пожалуйста, рассмотрите следующий код, в котором я создаю List<Interface1>. А затем get() элемент и отбросить его до Interface2 без ошибки компилятора, хотя эти два интерфейса полностью не связаны.

import java.util.*;

public class Main {
  public static void main(String ... args) {
    List<Interface1> list = new ArrayList<>();
    list.add(new Interface1() {});

    Interface1 ok = list.get(0);
    Interface2 why = (Interface2)list.get(0);
  }
}

interface Interface1 {
}

interface Interface2 {
}

Может ли кто-нибудь объяснить, почему не существует ошибки компилятора для трансляции на втором get(0)?

Две боковые заметки: Выполнение класса вызывает a ClassCastException (как и ожидалось). И использование двух классов вместо интерфейсов действительно порождает ошибки компиляции.

4b9b3361

Ответ 1

Это поведение не связано с дженериками: вы можете использовать любой интерфейс для любого другого без ошибок компиляции.

Вы не можете сделать это с помощью классов, потому что Java может проверять во время компиляции, может ли один класс быть отлит другим.

С интерфейсами, однако, передача может быть успешной или неудачной, в зависимости от класса, который фактически реализует интерфейс. Это можно обнаружить только во время выполнения.

Ответ 2

Если у вас есть тип, реализующий Interface1, он может также реализовать Interface2. Следовательно, компилятор не будет винить вас, потому что во время выполнения приведение может быть успешным.

Ответ 3

Это связано с тем, что JAVA поддерживает несколько реализаций интерфейса. Поскольку мы можем иметь любое количество классов любых типов (любой родительский класс), которые могут реализовывать интерфейс, конструкция JVM такова, что до времени выполнения нельзя определить, какой тип передается на месте этого интерфейса. Таким образом, может быть любой интерфейс, размещенный в ArryList

Ответ 4

Компилятор не знает, что это не сработает: у вас может быть экземпляр типа Interface2, который также имеет тип Интерфейс1 (для примера: класс РеализацияКлассирование реализует Interface1, Interface2). Тогда отливка будет прекрасной.

", используя два класса вместо интерфейсов, фактически генерирует ошибки компиляции."

В этих ситуациях компилятор знает, что это не сработает, и из-за этого вы получаете ошибку компиляции в этом случае.

Ответ 5

Существует возможность, что подкласс класса Interface1 также может быть подклассом Interface2. Таким образом, он не дает ошибку компиляции.

Ответ 6

Это не общая проблема. JVM ничего "не знает" о совместимости между Interface1 и Interface2. Итак, вы получаете ClassCastException.