Показаны сообщения с ярлыком generics. Показать все сообщения
Показаны сообщения с ярлыком generics. Показать все сообщения

вторник, 27 мая 2014 г.

Type Bounds

Существуют следующие ограничения типов:
  • upper bound - ключевое слово extends
  • lower bound - ключевое слово super.
При использовании wildcard тип передаваемого объекта можно:
  • не ограничивать
University unboundedUniversity;
University<?> sameUnboundedUniversity;
  • ограничивать снизу
University<? extends Student> lowerBoundedUniversity;
  • ограничивать сверху
University<? super Genius> upperBoundedUniversity

При объявлении параметризованного класса тип параметра можно ограничить только сверху, зато сразу несколькими ограничителями (правила наследования в силе - можно ограничить одним классов и любым количеством интерфейсов).

class University<T extends Student & Educable & Callable> 

пятница, 23 мая 2014 г.

Generics

Несколько важных штук о дженериках:
1. Type erasure (стирание типов). Означает, что проверка соответствие типов в дженериках проводится исключительно на этапе компиляции. Далее данные о типах будут стёрты.

List<Clever> geniuses = new ArrayList<>();
List<Stupid> losers = new ArrayList<>();
System.out.println(geniuses.getClass() == losers.getClass());  //true

2. Как следствие type erasure, нельзя создать массив дженериков.

class University<T> {
    T[] group = new T[30];  //error
}


3. Дженерики не коваринтны.

List<Student> students = new ArrayList<>();
students = new ArrayList<Clever>(); //ошибка компиляции


4. При использовании wildcard (<?>, <? extends T>, <? super T>) стоит помнить о принципе PECS - Producer Extends Consumer Super. Этот принцип гласит:
Если метод имеет аргументы с параметризованным типом (например, Collection<T> или Predicate<T>), то в случае, если аргумент — производитель (producer), нужно использовать ? extends T, а если аргумент — потребитель(consumer), нужно использовать ? super T.
Производитель и потребитель, кто это такие? Очень просто: если метод читает данные из аргумента, то этот аргумент —производитель, а если метод передаёт данные в аргумент, то аргумент является потребителем. Важно заметить, что определяя производителя или потребителя, мы рассматриваем только данные типа T.

Примеры производителя - коллекции, потребителя - предикаты.

5. Можно использовать множественные ограничения:

class University<T extends Student & Serializable>