Что такое Generics (обобщения) в Java?

«Что такое Generics (обобщения) в Java?» — вопрос из категории Основы программирования, который задают на 10% собеседований QA Тестировщик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Generics (обобщённые типы) — это механизм Java, позволяющий создавать классы, интерфейсы и методы, которые работают с типами, задаваемыми в качестве параметров. Это обеспечивает безопасность типов на этапе компиляции и устраняет необходимость в явном приведении типов.

Зачем это нужно? Без Generics коллекции хранили объекты типа Object, что вело к ошибкам ClassCastException во время выполнения.

Пример использования с коллекциями:

// Без Generics (устаревший, небезопасный способ)
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0); // Требуется явное приведение типа

// С Generics (типобезопасный способ)
List<String> strings = new ArrayList<>();
strings.add("hello");
String s = strings.get(0); // Приведение не требуется, компилятор знает тип
// strings.add(123); // Ошибка компиляции: несовместимые типы

Ключевые аспекты:

  • Type Erasure (стирание типов): Информация об обобщённых типах удаляется во время компиляции и недоступна во время выполнения. List<String> и List<Integer> становятся просто List.
  • Ограничения (Bounds): Можно ограничить типы параметров.
    // T должен быть подтипом Number
    public <T extends Number> void process(T number) { ... }
  • Wildcards (подстановочные знаки): ? используется для обозначения неизвестного типа.
    // Метод, принимающий список любого типа
    public void printList(List<?> list) { ... }

Преимущества: Повышение безопасности типов, переиспользуемость кода, лучшая читаемость.