Короткий ответ
Generics — это параметризованные типы: классы, интерфейсы и методы работают с типом, который задаётся при использовании, а не «зашит» в код. Главная решаемая проблема — типобезопасность и раннее обнаружение ошибок: компилятор проверяет типы на этапе компиляции, а не в рантайме, и убирает ручные приведения к Object.
Как это работает подробнее
До дженериков коллекции хранили Object, и при извлечении требовалось явное приведение, например к строке. Если в список по ошибке попал элемент другого типа, программа падала с ClassCastException в рантайме, часто далеко от места добавления. С дженериками неверный тип не проходит компиляцию — проверки выполняются на этапе компиляции.
Механизм работает с классами, интерфейсами и методами: тип-параметр задаётся при использовании (класс с параметром T, дженерик-методы и дженерик-интерфейсы). Параметром может быть только ссылочный тип — примитив нужно оборачивать в класс-обёртку (Integer вместо int). Информация о типе-параметре существует только до компиляции: в рантайме она стирается.
- Коллекция «знает» тип своих элементов: список, параметризованный строкой, не примет число.
- Код становится самодокументируемым и не требует шаблонных приведений типов.
Пример кода
import java.util.ArrayList;
import java.util.List;
public class GenericsDemo {
public static void main(String[] args) {
List<String> words = new ArrayList<>();
words.add("java");
// words.add(42); // не скомпилируется
String first = words.get(0); // без приведения типов
System.out.println(first.toUpperCase());
}
}Что использовать на практике
- Коллекции всегда объявляйте с параметром типа — это включает проверки компилятора.
- Для переиспользуемых структур пишите собственные дженерик-классы и методы.
- Примитивы в дженериках используйте через классы-обёртки (
Integer,Long).
Подводные камни
- Сырой тип (
Listбез параметра) отключает проверки и возвращает рискClassCastException. - Примитив как параметр типа не скомпилируется — только ссылочные типы.
- Параметр типа недоступен в рантайме: проверить параметризованный тип через
instanceofнельзя.
Как отвечать на собеседовании
- Каркас: дайте определение — параметризованные типы → назовите проблему: коллекции
ObjectиClassCastExceptionв рантайме → скажите, что дженерики переносят проверки на этап компиляции → приведите пример параметризованной коллекции → добавьте ограничение: только ссылочные типы и стирание в рантайме.