Горячая вакансия – релокация в Берлин! Узнать подробности...
Горячая вакансия – релокация в Берлин! Узнать подробности...

Как ограничивается тип generic параметра?

Посмотреть в Telegram: @JavaSobes/60
В объявлении дженерик-параметра класса или метода может быть указана его верхняя граница (bound):

class Foo<T extends Number>

Ключевое слово extends применяется как для классов, так и для интерфейсов. Фактическим параметром такого класса Foo может быть или сам Number, или его наследники.

Помимо ограничения возможных применяемых типов, bounded-параметр дает право использовать в реализации методы и поля типа-ограничителя – он будет как минимум предком фактического типа. Это достигается стиранием типа-параметра до верхней границы.

Тип-параметр может иметь несколько верхних границ, то есть границу-пересечение типов: <T extends Comparable & Serializable>. Стирание произойдет до первой из границ, остальные послужат только ограничением вариантов фактического типа. Поэтому граница-класс, при наличии, должна быть указана раньше границ-интерфейсов.
При указании значения дженерик-параметра переменной может быть использован вайлдкард – символ ?. Вайлдкард значит, что мы не собираемся использовать информацию о конкретном типе, этот тип может быть любым. Это не то же самое, что не указать дженерик параметр совсем.

Для вайлдкарда также как и для объявления типа-параметра можно обозначить верхнюю границу. Но в отличие от объявления, здесь нельзя использовать пересечение типов, по крайней мере пока.

Кроме того, в случае вайлдкарда можно задать нижнюю границу:

Foo<? super Number> foo;

Означает, что мы не будем использовать информацию о конкретном типе, но будем знать что это предок класса Number. То есть или сам Number, или Object.

В объявлении класса или метода использование super запрещено, так как не имеет смысла.

Лучше разобраться в механике использования ограниченных вайлдкардов поможет это видео.

Хороший API должен уметь эффективно работать с классами-наследниками, то есть быть ко- или контравариантным где это необходимо. При этом без bounded вайлдкардов не обойтись. Чтобы запомнить, какая граница нужна в каких случаях, Joshua Bloch предложил мнемонику PECS: Producer-extends, Consumer-super.