Ответ
Generics в Java реализуют принцип параметрического полиморфизма (parametric polymorphism). Это позволяет создавать классы, интерфейсы и методы, которые работают с типами, указанными в качестве параметров. Основная цель — обеспечить безопасность типов (type safety) на этапе компиляции и исключить необходимость в ненадёжном приведении типов (casting).
Пример и сравнение:
// Без Generics (ненадёжно, требует приведения)
List rawList = new ArrayList();
rawList.add("Hello");
String s = (String) rawList.get(0); // Явный cast, риск ClassCastException
// С Generics (безопасно на этапе компиляции)
List<String> genericList = new ArrayList<>();
genericList.add("Hello");
String s = genericList.get(0); // Автоматический и безопасный вывод типа
// genericList.add(42); // Ошибка компиляции: несовместимые типы
Как это связано с принципами ООП:
- Полиморфизм: Generics — это форма ad-hoc (параметрического) полиморфизма, в отличие от полиморфизма подтипов (наследование/интерфейсы). Код становится полиморфным относительно типов-параметров.
- Инкапсуляция и повторное использование: Generics позволяют инкапсулировать алгоритмы, не зависящие от конкретного типа, в обобщённые классы (например,
List<T>,Comparator<T>), что значительно повышает повторное использование кода. - Не является принципом: Generics сами по себе — это языковой механизм, а не базовый принцип ООП. Они реализуют и усиливают принципы полиморфизма и инкапсуляции в контексте типобезопасности.
Важное ограничение — стирание типов (Type Erasure): Информация о generic-типах удаляется во время компиляции и недоступна во время выполнения (Runtime). List<String> и List<Integer> в runtime — это просто List. Это накладывает ограничения, например, нельзя создать массив new T[] или проверить instanceof T.