Generics

Проработать

  1. Advanced Java - Generics
  2. Пришел, увидел, обобщил: погружаемся в Java Generics
  3. Обобщения (Generic)
  4. Использование generic wildcards для повышения удобства Java API
  5. Generics
  6. Использование wildcard в Generics Java
  7. Урок 10 - Generics, Collections - Java для тестировщиков
  8. Обобщения (Generics)
  9. Generics In Java - Full Simple Tutorial

Generics - это подход к реализации класса, который позволяет использовать его с различными типами данных без изменения его реализации.

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

При сравнении Set<String> и Set<Integer> будет true. Тк. type erasure при компиляции заменить все на Object.

Но List<String> не является наследником List<Object> - Инвариантность.

List<String> strings = new ArrayList<String>();
// ошибка компиляции!
List<Object> objects = strings;
        

Способы использования

Конвенция наименования типов

Ключевые слова для ограничений.

Используется для создания ковариантности и контравариантности. Тк по умолчанию generics инвариантны.

  1. extend - ограничивает типизацию до указанного класса и его потомков.

    И стирания типа при компиляции будет до указанного класса, а не до Object.

    <T extend Animal>
                    
  2. super - ограничивает типизацию от Object до указанного класса.

    И стирания типа при компиляции будет до Object.

    <? super Animal>
                    

Параметризованный тип не может использовать ограничение super(только extend), как WildCard.

public void print(List<? super Integer> list)  // OK
//but you can't use type parameter:
 public <T super Integer> void print(List<T> list)  // Won't compile
        

Multiple bounds

Multiple bounds - возможность добавлять несколько ограничений.

<T extends B1 & B2 & B3>
        

WildCard

WildCard обозначается знаком "?". Необходим когда мы не будем указывать тип generic вручную. Но мы не можем создавать связь между указанным типом в реализации.

Пример с типизацией:
public static <T extends Number> void copy(List<T> dest, List<T> src)
Пример с WildCard:
public static void copy(List<? extends Number> dest, List<? extends Number> src)
        

? and ? extends Object - это одно и тоже.

WildCard не поддерживает "multiple bounds".

PECS

>PECS - правило при использовании WILDCARD c коллекциями. Позволяет добавить Ковариантность или Контравариантность в коллекции.

Условия:

<? extends A>

  1. Можно передать коллекцию с generic <A> или generic <subclass A>.
  2. Можно добавлять в коллекцию(кроме null), но можем выполнять действия над элементами.
public void sendEmailsFixed(List<? extends User> users) {}
List<Customer> customers = Arrays.asList(new Customer("john"), new Customer("arys"));
sendEmailsFixed(customers);
        

<? super A>

private void addUsersFromMarketingDepartmentFixed(List<? super Operator> users) {
users.add(new Operator("john doe"));