Назад к вопросам
Middle
70
questionbank

Какие есть возможности в Generics?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Generics позволяют создавать параметризованные классы, интерфейсы и методы.

Основные возможности:

  • Переиспользование кода: Создание универсальных структур данных и алгоритмов, работающих с любыми типами.
  • Безопасность типов во время компиляции: Ошибки типизации обнаруживаются на этапе компиляции, а не выполнения. Снимает необходимость в ручном приведении типов и связанных с этим потенциальных ошибок ClassCastException.
  • Улучшенная читаемость: Код становится более понятным, так как явно указывает, с какими типами он работает.

Примеры:

  • Класс-контейнер List<T> может хранить элементы любого типа T.
  • Метод static <T> T getFirst(List<T> list) может возвращать первый элемент из списка любого типа.

Ограничения Generics:

  • Нельзя создавать экземпляры обобщенного типа: new T().
  • Нельзя использовать примитивные типы в качестве параметров типа (например, List<int> - неверно, нужно List<Integer>).
  • Нельзя создавать массивы обобщенных типов напрямую (например, T[] array = new T[10] - неверно, нужно использовать ArrayList или приведение типов).
  • Нельзя использовать статические поля обобщенного типа напрямую.
  • Информация о типах стирается на этапе выполнения (Type Erasure), за исключением bounded wildcards.

Wildcards и Bounded Type Parameters:

  • <?>: Неизвестный тип. Позволяет читать элементы, но не писать.
  • <? extends T>: Ограничение сверху. Позволяет работать с типами, которые являются подтипами T. Можно читать элементы типа T или его супертипов, но не писать (кроме null).
  • <? super T>: Ограничение снизу. Позволяет работать с типами, которые являются супертипами T. Можно писать элементы типа T или его подтипов, но читать только элементы типа Object.

Пример:

// Метод, который может печатать элементы из любого списка,
// который содержит подтипы Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Ошибка компиляции
}

// Метод, который может добавлять Integer в список,
// который содержит Integer или его супертипы
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Ошибка компиляции, возвращает Object
}