2013-10-03 3 views
1

Рассмотрим те следующий код:Сырье типа и подтипов

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 

    } 
} 

Я прочитал "What is a raw type and why shouldn't we use it?" тему. Следовательно, если у нас есть параметризованный тип MyClass<T>, то путем сбрасывания исходного типа мы можем определить ссылку MyClass m на тип raw во время компиляции. Кроме того, необработанный тип MyClass, соответствующий заданному параметризованному типу MyClass<T>, является суперклассом MyClass<E>во время компиляции до стирания типа для всего конкретного типа E. Правильно ли эта причина?

+0

Что вы не поняли из этого сообщения, которое содержит лучшее объяснение по этой теме? –

+0

@Rohit Jain Я не понимаю, как работает компилятор, когда он нашел ссылку на необработанный тип или инициировал необработанный тип. Первый тип проверки, т. Е. «Список ints = new ArrayList ()' вызывает ошибку времени компиляции. После того, как тип проверки компилятора начал стирать тип. В случае с сырым типом: 'List lst = new ArrayList()' какой компилятор делает? Нет типа для проверки и стирания? И почему 'List lst = new ArrayList ()' и 'List lst = new ArrayList()' правильный? Означает ли это, что тип raw является супертипом и подтипом для всех родовых типов во время компиляции до стирания стилей? –

ответ

2

От Angelika Langer's Generics FAQ:

сырых типов супертипы все бетона и все шаблонные конкретизации родового типа. Например, необработанный тип Collection является супертипом всех экземпляров родового типа Collection.

generic type hierarchy

В статье продолжается:

В отношении конверсии, обычного расширения опорного преобразования из подтипа в супертипе допускается. То есть, каждое создание типичного типа может быть преобразовано в соответствующий тип raw. Реверс допускается также по соображениям совместимости между родовыми и неэквивалентными типами. Это так называемое непроверенное обращение и сопровождается «непроверенным» предупреждением.

Для решения ваших дальнейших вопросов в комментарии:

В случае необработанного типа: List lst= new ArrayList(), что компилятор делает? Нет типа для проверки и стирания?

Нет общий тип проверки. Очевидно, что компилятор по-прежнему уверен, что ArrayList назначается List. Здесь ничего особенного не существует - такой код обычно записывался до того, как дженерики добавляются в язык. Теперь он по-прежнему допускает обратную совместимость, но компилятор предупредит вас об использовании необработанных типов.

И почему List lst= new ArrayList<String>() и List<Integer> lst= new ArrayList() верны?

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

Означает ли это, что необработанный тип является супертипом и подтипом для всех родовых типов во время компиляции до стирания стилей?

Как указано в FAQ Generics, необработанный тип является супертипом всех его общих вариантов. Причина, по которой назначение разрешено в обоих направлениях, заключается в том, что необработанные типы «отказываются» от проверки общего типа, поэтому использование их по обе стороны от назначения неявно делает непроверенным преобразованием.Еще раз, компилятор предупредит вас об этом, так как он угрожает безопасности типов.

Смежные вопросы