Ответ
В Java Generics могут использоваться только ссылочные типы (reference types). Примитивные типы (int, char и т.д.) напрямую не поддерживаются, но их можно использовать через соответствующие классы-обертки (Integer, Character).
Почему только ссылочные типы? Generics реализованы через механизм стирания типов (type erasure) во время компиляции, который работает с Object и его подтипами. Примитивы не наследуются от Object.
Примеры допустимых типов:
-
Классы:
class Container<T> { private T item; public void set(T item) { this.item = item; } public T get() { return item; } } Container<String> stringContainer = new Container<>(); Container<Integer> intContainer = new Container<>(); -
Интерфейсы:
List<String> list = new ArrayList<>(); Map<Integer, String> map = new HashMap<>(); -
Массивы (как тип):
List<String[]> listOfArrays = new ArrayList<>();
Важно: Начиная с Java 7, для сокращения кода используется diamond operator <>, который позволяет компилятору вывести тип из контекста.
Ответ 18+ 🔞
Давай разберёмся с этим дженерик-делом, а то у некоторых мозг набекрень встаёт, как только видят эти угловые скобочки. Ну, типа, <T> там всякие.
Смотри, в Java эти ваши Generics — они, блядь, исключительно для ссылочных типов. То есть всякие String, Integer, MySuperPuperClass. А вот примитивы — int, char и прочая мелочь — нихуя не прокатят напрямую. Совсем. Как будто их нет, понимаешь?
А почему, спрашивается, такая хуйня? А потому что внутри, на этапе компиляции, происходит так называемое стирание типов (type erasure). Короче, компилятор берёт всё это <T> и превращает в Object, а потом уже кастит обратно, куда надо. А Object — он же отец всех классов, но примитивы — они сироты, блядь, не от него. Вот и вся магия, ёпта.
Но выход есть, не ссы! Берёшь классы-обёртки — Integer вместо int, Character вместо char — и вуаля, всё работает. Немного писанины добавится, но жить можно.
Примерчики, чтобы въехать:
-
Свой класс, чтоб свой:
class Container<T> { private T item; public void set(T item) { this.item = item; } public T get() { return item; } } // Строки — пожалуйста Container<String> stringContainer = new Container<>(); // Целые числа — да не вопрос, через Integer Container<Integer> intContainer = new Container<>(); -
Стандартные интерфейсы — там вообще красота:
List<String> list = new ArrayList<>(); Map<Integer, String> map = new HashMap<>(); -
Массивы тоже можно, но осторожно:
List<String[]> listOfArrays = new ArrayList<>();
Лайфхак на миллион, блядь: С седьмой Java появился алмазный оператор <>. Вместо того чтобы писать new ArrayList<String>(), можно просто new ArrayList<>(). Компилятор не дурак, он сам сообразит, что ты имел в виду. Экономия времени и нервов — овердохуища!