Вопрос-ответ

Why can Java Collections not directly store Primitives types?

Почему коллекции Java не могут напрямую хранить типы примитивов?

Коллекции Java хранят только объекты, а не примитивные типы; однако мы можем хранить классы-оболочки.

Почему это ограничение?

Переведено автоматически
Ответ 1

Это было дизайнерское решение Java, которое некоторые считают ошибочным. Контейнерам нужны объекты, а примитивы не являются производными от Object .

Это одно из мест, где .СЕТЕВЫЕ разработчики извлекли уроки из JVM и внедрили типы значений и обобщения таким образом, что во многих случаях боксирование исключено. В CLR универсальные контейнеры могут хранить типы значений как часть базовой структуры контейнера.

Java решила добавить 100% универсальную поддержку в компилятор без поддержки со стороны JVM. JVM, как она есть, не поддерживает "необъектный" объект. Дженерики Java позволяют вам притворяться, что оболочки нет, но вы все равно платите за производительность упаковки. Это ВАЖНО для определенных классов программ.

Упаковка - это технический компромисс, и я чувствую, что это утечка деталей реализации в язык. Автоматическая упаковка - хороший синтаксический сахар, но все равно снижает производительность. Во всяком случае, я бы хотел, чтобы компилятор предупреждал меня при автоматической загрузке. (Насколько я знаю, сейчас это возможно, я написал этот ответ в 2010 году).

Хорошее объяснение в SO о боксировании: Почему некоторым языкам требуется боксирование и распаковка?

И критика дженериков Java: Почему некоторые утверждают, что реализация дженериков Java плоха?

В защиту Java можно сказать, что легко оглянуться назад и подвергнуть критике. JVM выдержала испытание временем и является хорошим дизайном во многих отношениях.

Ответ 2

Упрощает реализацию. Поскольку примитивы Java не считаются объектами, вам потребуется создать отдельный класс коллекции для каждого из этих примитивов (без использования шаблонного кода).

Вы, конечно, можете это сделать, просто посмотрите GNU Trove, Apache Commons Primitives или HPPC.

Если у вас нет действительно больших коллекций, накладные расходы на оболочки не имеют достаточного значения, чтобы люди заботились об этом (и когда у вас есть действительно большие коллекции примитивов, вы можете захотеть потратить усилия на изучение использования / создания специализированной структуры данных для них).

Ответ 3

Это комбинация двух фактов:


  • Примитивные типы Java не являются ссылочными типами (например, an int не является Object)

  • Java создает дженерики, использующие стирание типов ссылочных типов (например, a List<?> действительно является a List<Object> во время выполнения)

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

Этого можно было избежать? Возможно.


  • Если int это Object , то в типах блоков вообще нет необходимости.

  • Если обобщения не выполняются с использованием стирания типов, то для параметров типа могли использоваться примитивы.

Ответ 4

Существует концепция автоматической упаковки и автоматической распаковки. Если вы попытаетесь сохранить an int в a List<Integer>, компилятор Java автоматически преобразует его в an Integer.

java collections