Sobes.tech
Назад к вопросам
Senior
3

Расскажите, что такое дженерики в Java и в чём различия между инвариантностью, ковариантностью и контравариантностью при их использовании?

Компании, где спрашивали
Северсталь

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

sobes.tech AI

Дженерики в Java позволяют создавать классы, интерфейсы и методы с параметрами типов, что обеспечивает типобезопасность и переиспользуемость кода без необходимости кастов.

Инвариантность означает, что параметр типа должен точно совпадать. Например, List<String> не является подтипом List<Object>.

Ковариантность позволяет использовать более конкретный тип, чем ожидается. В Java это реализуется через wildcard с extends: List<? extends Number> — можно читать элементы как Number, но нельзя добавлять.

Контравариантность — наоборот, позволяет использовать более общий тип. В Java это wildcard с super: List<? super Integer> — можно добавлять Integer и его подтипы, но при чтении получаем Object.

Пример:

List<? extends Number> numsCovariant = new ArrayList<Integer>();
Number n = numsCovariant.get(0); // чтение разрешено
// numsCovariant.add(10); // ошибка компиляции

List<? super Integer> numsContravariant = new ArrayList<Number>();
numsContravariant.add(10); // добавление разрешено
Object obj = numsContravariant.get(0); // чтение возвращает Object

Таким образом, ковариантность удобна для чтения, контравариантность — для записи.