2012-07-09 2 views
2

Я заметил, что необработанный тип универсального класса может принимать (указывать) все различные варианты родового класса, а также все различные варианты общего класса могут принимать (указывать) необработанный тип родового класса. Почему Java Generics ведет себя так? Это просто из-за совместимости со старыми версиями Java?Тот факт, что необработанный тип родового класса может принимать все различные варианты этого общего класса, является вопросом совместимости с Java?

Пример:

//Main.java 
public class Main { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

    List listRaw = new ArrayList(); 
    List<Student> listQualified = new ArrayList<Student>(); 
    List<?> listUnbounded = new ArrayList<Student>(); 
    List<? extends Student> listUpBounded = new ArrayList<Student>(); 
    List<? super Student> listDownBounded = new ArrayList<Student>(); 

    // List raw type can take all different variations of List 
    List rawList1 = listRaw; 
    List rawList2 = listQualified; 
    List rawList3 = listUnbounded; 
    List rawList4 = listUpBounded; 
    List rawList5 = listDownBounded; 

    // All different variations of List can take List raw type 
    listRaw = rawList1; 
    listQualified = rawList2; 
    listUnbounded = rawList3; 
    listUpBounded = rawList4; 
    listDownBounded = rawList5; 

    } 

} 

//People.java 
public class People { 

    public static class Student extends People { 
    } 

    public class HistoryStudent extends Student { 
    } 

    public class MathStudent extends Student { 
    } 
} 

ответ

4

Одна из главных проблем, стоящих перед инженерами Sun, заключалась в поддержании обратной совместимости. Например, если вы не можете назначить:

List list = new ArrayList<Student>(); 

тогда, вы не могли бы использовать старые библиотечные методы. т.е.

List org.apache.commons.collections.ListUtils.intersection(List arg0, List arg1) 

Также помните эти типы исчезают во время выполнения, как описаны на http://docs.oracle.com/javase/tutorial/java/generics/erasure.html

+0

Спасибо, Ale, так что это в основном по соображениям совместимости. –

1

Да. Фактически в java 5 добавлены дженерики, и язык должен был поддерживать совместимость с предыдущими версиями. Этот компромисс работает, потому что информация об общей информации исчезает после того, как код скомпилирован (тип ereasure) в .class, даже если вы можете иметь информационное отражение, если некоторые методы принимают параметры типового типа. Если вы скомпилируете код, аналогичный тому, что вы написали, он работает нормально, но обычно компилятор предупреждает вас, что вы используете «сырые» типы.

+0

но это не объясняет, почему вы можете назначить между параметризованными и сырыми типами – newacct

+0

, потому что все параметризованные типы присваиваемы исходными типами , По его словам, это связано с стиранием типа, в основном, для обратной совместимости. Компилятор предупреждает вас об этом, и вы можете сказать, что он отключился от аннотации @SuppressWarnings («rawtypes»). – Matt

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

  • Нет связанных вопросов^_^