Тип сырья и подтип
Рассмотрим следующий код:
public class MyClass<T>{
T data;
public MyClass(T data){ this.data=data; }
}
public class Main{
public static void main(String[] args){
MyClass m= new MyClass<Integer>(3);// ok
}
}
Я прочитал тему " Что такое необработанный тип и почему мы не должны его использовать?". Следовательно, если у нас есть параметризованный тип MyClass<T>
тогда по определению необработанного типа мы можем определить ссылку MyClass m
в сырой тип во время компиляции. Кроме того сырой тип MyClass
соответствует данному параметризованному типу MyClass<T>
это суперкласс MyClass<E>
во время компиляции перед стиранием типа для всех определенных типов E
, Правильна ли эта причина?
1 ответ
Из часто задаваемых вопросов об Анжелике Лангер:
необработанные типы - это супертипы всех конкретных и всех шаблонных экземпляров универсального типа. Например, необработанный тип
Collection
является супертипом всех экземпляров универсального типаCollection
,
Статья продолжается:
Что касается преобразований, то допускается обычное преобразование с расширением ссылок из подтипа в супертип. То есть каждый экземпляр универсального типа может быть преобразован в соответствующий необработанный тип. Обратное также разрешено по причинам совместимости между универсальными и неуниверсальными типами. Это так называемое непроверенное преобразование, сопровождаемое "непроверенным" предупреждением.
Чтобы ответить на ваши дальнейшие вопросы в комментарии:
В случае необработанного типа:
List lst= new ArrayList()
что делает компилятор? Нет типа для проверки и удаления?
Там нет общей проверки типов. Очевидно, что компилятор все еще проверяет ArrayList
присваивается List
, Ничего специфичного для генериков здесь не происходит - подобный код, как правило, был бы написан до добавления обобщений в язык. Теперь это все еще разрешено для обратной совместимости, но компилятор предупредит вас об использовании необработанных типов.
И почему
List lst= new ArrayList<String>()
а такжеList<Integer> lst= new ArrayList()
верно?
Правильно только то, что он успешно компилируется, но это не лучшая практика и вызовет предупреждения компилятора как для необработанных типов, так и для непроверенных преобразований.
Означает ли это, что необработанный тип является супертипом и подтипом для всех универсальных типов во время компиляции перед удалением типа?
Как указано в Generics FAQ, необработанный тип является супертипом всех его общих вариантов. Причиной того, что присваивание разрешено в обоих случаях, является то, что необработанные типы "отказываются" от проверки универсального типа, поэтому их использование по обе стороны от присваивания неявно выполняет непроверенное преобразование. Еще раз, компилятор предупредит вас об этом, так как это угрожает безопасности типов.