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

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

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

7 ответов


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

Это одно место, которое .NET-дизайнеры узнали из JVM и реализовали типы значений и дженерики, такие, что бокс во многих случаях устраняется. В среде CLR универсальные контейнеры могут хранить типы значений как часть базовой структуры контейнера.

Java решила добавить общую поддержку 100% в компилятор без поддержки со стороны виртуальная машина Java. JVM, будучи тем, что он есть, не поддерживает объект "не-объект". Java generics позволяет вам притворяться, что нет обертки, но вы все равно платите цену производительности бокса. Это важно для определенных классов программ.

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

хорошее объяснение по поводу бокса:почему некоторые языки нуждаются в боксе и распаковке?

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

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


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

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

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


это сочетание двух фактов:

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

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

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

  • если int Это Object, тогда нет необходимости в типах полей вообще.
  • если дженерики не выполняются с использованием стирания типа, то примитивы могли использоваться для параметров типа.

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


Это не ограничение это?

подумайте, хотите ли вы создать коллекцию, в которой хранятся примитивные значения. Как бы вы написали коллекцию, которая может хранить int, float или char? Скорее всего, вы получите несколько коллекций, поэтому вам понадобится intlist и charlist и т. д.

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


Я думаю, что мы можем увидеть прогресс в этом пространстве в JDK, возможно, в Java 10 на основе этого JEP -http://openjdk.java.net/jeps/218.

Если вы хотите избежать бокса примитивов в коллекциях сегодня, есть несколько сторонних альтернатив. В дополнение к ранее упомянутым сторонним опциям существует также Коллекции Eclipse, FastUtil и Koloboke.

сравнение примитивных карт также опубликовано некоторое время назад с названием: Большой обзор HashMap:JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove. Библиотека GS Collections (Goldman Sachs) была перенесена в Eclipse Foundation и теперь является коллекциями Eclipse.


основной причиной является стратегия проектирования java. ++ 1) коллекции требуют объектов для манипулирования, а примитивы не являются производными от object так что это может быть другой причиной. 2) примитивные типы данных Java не являются ссылочным типом для ex. int не является объектом.

Преодолеть:-

У нас есть концепция автоматического бокса и автоматического распаковки. поэтому, если вы пытаетесь сохранить примитивные типы данных, компилятор автоматически преобразует их в объект этих примитивных данных класс.