Новичок Java: дженерики по объектам только?

Я плохо знаком с Java. При кодировании Карты <>, я узнал то объявление Map<int, int> синтаксическая ошибка в то время как Map<Integer, Integer> в порядке. Действительно ли только возможно в Java инстанцировать дженериков по типам объектов, в противоположность примитивам? Если так, есть ли значимая потеря производительности для упаковки/распаковывания примитивов?

8
задан tzaman 10 June 2010 в 15:15
поделиться

4 ответа

Да, вы можете использовать ссылочные типы только для параметров общих типов, и да, будет некоторое снижение производительности из-за боксирования/небоксирования (которое может быть сделано автоматически по большей части).

Вот цитата из Java Generics FAQs:

Разрешено ли использовать примитивные типы в качестве аргументов типа?

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

[...] Обратите внимание, что отсутствие инстанцирования примитивных типов приводит к снижению производительности. Автобоксинг и -унбоксинг делают использование инстанцирования оберточных типов общих типов очень удобным и лаконичным в исходном коде. Но краткая нотация скрывает тот факт, что за занавесом виртуальная машина создает и использует множество объектов-оберток, каждый из которых должен быть выделен, а затем собран. Более высокая производительность прямого использования значений примитивных типов не может быть достигнута с помощью общих типов. Только обычный тип может обеспечить оптимальную производительность использования значений примитивных типов.

Если вам абсолютно необходима производительность, Trove имеет множество структур данных, специализированных для примитивных типов, но для большинства практических целей использование коробочных примитивных типов с классами Java Collections Framework должно обеспечить более чем приемлемую производительность.

См. также

11
ответ дан 5 December 2019 в 11:22
поделиться

Возможно ли только в Java создать экземпляры дженериков над объектом типы, в отличие от примитивов?

правильно.

Если да, то есть ли заметный штраф за исполнение бокс / распаковка примитивов?

да, есть.

См. Подробное описание здесь: http://java.sun.com/j2se/1.5.0/docs/guide/language/autoboxing.html

2
ответ дан 5 December 2019 в 11:22
поделиться

Как отмечали другие, использование классов-оберток для примитивов приводит к снижению производительности. И хотя цена не очень заметна, если вам РЕАЛЬНО нужен дополнительный прирост производительности, вы можете просто создать пользовательские подклассы для класса List, по одному для каждого типа примитива (их не так много, так что это не проблема) и просто переопределить методы, которые помещают и получают значения в списке, и ограничить их приемом каждого примитива. Это даст прирост производительности и сохранит многословность кода общего списка.

0
ответ дан 5 December 2019 в 11:22
поделиться

1) Да, дженерики Java работают только с объектными типами. Это связано с тем, как они реализованы, то есть через стирание типов - по сути, после компиляции в байткод все generic-типы заменяются на Object - это было сделано для того, чтобы java generics могли работать без модификации базовой JVM/байткода (плохое решение, имо).

2) Да, будет некоторый штраф за боксирование / дебоксирование; боюсь, этого не избежать.

2
ответ дан 5 December 2019 в 11:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: