Этот вопрос проверяет понимание дженериков в Java/Kotlin, а именно ковариантности (extends) и контравариантности (super).
<? extends T> — позволяет использовать T и его подклассы (ковариантность, только чтение).
<? super T> — позволяет использовать T и его суперклассы (контравариантность, только запись).
1. <? extends T> (Producer):
Можно: Читать элементы как T (безопасно, так как все элементы — подтипы T).
Нельзя: Добавлять элементы (кроме null), так как неизвестен точный подтип.
Пример:
fun printNumbers(list: List<out Number>) {
for (num in list) println(num) // OK: Number, Int, Double и т.д.
// list.add(10) // Ошибка!
} 2. <? super T> (Consumer):
Можно: Добавлять элементы типа T (безопасно, так как контейнер принимает T и его предков).
Нельзя: Читать элементы как T (может вернуть Any?).
Пример:
fun addNumbers(list: MutableList<in Int>) {
list.add(10) // OK
// val num: Int = list[0] // Ошибка!
} 3. PECS (Producer-Extends, Consumer-Super):
Правило: Используйте extends для источников данных (чтение), super для приемников (запись).
Вывод:
extends — для безопасного чтения.
super — для безопасной записи.