Wildcard и PECS в API
Вопрос
Как бы вы спроектировали сигнатуру метода addAll(коллекция, элементы) и метода max(коллекция, компаратор), чтобы они были максимально гибкими?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Инвариантность дженериков и зачем нужны wildcard
addAll: Collection<? super T> приёмник, элементы как producer
max: Collection<? extends T> и Comparator<? super T>
PECS как правило выбора
Wildcard только в параметрах, не в возвращаемых типах
Что могут спросить следом
- Почему в
Collections.maxграницаT extends Object & Comparable<? super T>? - Когда лучше дженерик-параметр метода, а когда wildcard?
Разбор
Дженерики инвариантны, поэтому без wildcard метод с Collection<T> примет только точное совпадение типов. Применяю PECS. addAll кладёт элементы в коллекцию, коллекция потребитель: static <T> boolean addAll(Collection<? super T> c, T... elements), тогда Integer можно добавить в List<Number>. max читает элементы, коллекция производитель: Collection<? extends T>, а компаратор потребляет T, поэтому Comparator<? super T>: компаратор для Number подойдёт для Integer. В возвращаемых типах wildcard не ставлю, иначе вызывающему неудобно. Если параметр встречается один раз, wildcard читается проще, если нужно связать несколько аргументов одним типом, ввожу параметр метода.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.