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

В какие направления может быть направлена вариантность в дженериках?

Sobes Copilot

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

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

sobes.tech AI

Вариантность в дженериках может быть направлена в три основных направления:

  • Ковариантность (Covariance): Позволяет использовать тип, который является подтипом указанного в дженерике. Обозначается модификатором out (в Kotlin) или ключевым словом extends (в Java, для ограниченных wildcard). Позволяет только читать из коллекции или обобщенного типа.
  • Контравариантность (Contravariance): Позволяет использовать тип, который является супертипом указанного в дженерике. Обозначается модификатором in (в Kotlin) или ключевым словом super (в Java, для ограниченных wildcard). Позволяет только записывать в коллекцию или обобщенный тип.
  • Инвариантность (Invariant): Тип должен быть точно таким же, как указано в дженерике. Используется по умолчанию в Kotlin и Java. Не позволяет использовать подтипы или супертипы.

Примеры:

// Ковариантность (out)
interface Producer<out T> {
    fun produce(): T
}

// Контравариантность (in)
interface Consumer<in T> {
    fun consume(item: T)
}

// Инвариантность (по умолчанию)
interface Container<T> {
    fun getItem(): T
    fun putItem(item: T)
}
// Ковариантность (extends - ограниченный wildcard)
List<? extends Number> covariantList = new ArrayList<Integer>(); // OK

// Контравариантность (super - ограниченный wildcard)
List<? super Integer> contravariantList = new ArrayList<Number>(); // OK

// Инвариантность (по умолчанию)
List<Number> invariantList = new ArrayList<Number>(); // OK
// List<Number> invariantListError = new ArrayList<Integer>(); // Error