Коллекции Java хранят только объекты, а не примитивные типы; однако мы можем хранить классы-оболочки.
Почему это ограничение?
java
collections
types
primitive-types
JavaUser
источник
источник
class
, а скорее JVM. Операторint i = 1
определяет указатель на одноэлементный экземпляр объекта, который определяетсяint
в JVM, установленный на значение,1
определенное где-то в JVM. Да, указатели в Java - это просто абстрагирование от вас с помощью языковой реализации. Примитивы нельзя использовать в качестве универсальных, потому что предикаты языка всех универсальных типов должны относиться к супертипу,Object
поэтому ониA<?>
компилируютсяA<Object>
во время выполнения.Ответы:
Это было дизайнерское решение Java, которое некоторые считают ошибкой. Контейнеры хотят, чтобы объекты и примитивы не были производными от Object.
Это то место, которое разработчики .NET извлекли из JVM и реализовали типы значений и обобщения, так что во многих случаях упаковка исключена. В среде CLR универсальные контейнеры могут хранить типы значений как часть базовой структуры контейнера.
Java решила добавить 100% универсальную поддержку в компилятор без поддержки JVM. JVM, какова она есть, не поддерживает «не объектный» объект. Дженерики Java позволяют вам притвориться, что оболочки нет, но вы все равно платите цену производительности бокса. Это ВАЖНО для определенных классов программ.
Бокс - это технический компромисс, и я чувствую, что детали реализации просачиваются в язык. Автобоксинг - хороший синтаксический сахар, но все же снижает производительность. Во всяком случае, я бы хотел, чтобы компилятор предупреждал меня, когда он автоматически упаковывается. (Насколько я знаю, возможно, сейчас я написал этот ответ в 2010 году).
Хорошее объяснение SO о боксе: зачем некоторым языкам нужны бокс и распаковка?
И критика дженериков Java: почему некоторые утверждают, что реализация дженериков в Java плохая?
В защиту Java легко оглянуться назад и критиковать. JVM выдержала испытание временем и во многих отношениях является хорошей разработкой.
источник
Object.ReferenceEquals
ссылок типа,Object
которые идентифицируют упакованные целые числа, но это не должно быть законным для передать целочисленное значение]. Автоматическая распаковка Java - это ИМХО просто противно.Облегчает реализацию. Поскольку примитивы Java не считаются объектами, вам нужно будет создать отдельный класс коллекции для каждого из этих примитивов (без кода шаблона для совместного использования).
Вы, конечно, можете сделать это, просто ознакомившись с GNU Trove , Apache Commons Primitives или HPPC .
Если у вас нет действительно больших коллекций, накладные расходы на обертки не имеют большого значения для людей (а когда у вас действительно большие примитивные коллекции, вы можете потратить усилия на использование / построение для них специализированной структуры данных ).
источник
Это сочетание двух фактов:
int
не являетсяObject
)List<?>
действительноList<Object>
во время выполнения)Поскольку оба эти утверждения верны, общие коллекции Java не могут напрямую хранить примитивные типы. Для удобства введено автобоксирование, позволяющее автоматически упаковывать примитивные типы как ссылочные типы. Однако не заблуждайтесь, коллекции по-прежнему хранят ссылки на объекты.
Можно ли этого избежать? Может быть.
int
- этоObject
, то типы боксов вообще не нужны.источник
Есть понятие авто-бокса и авто-распаковки. Если вы попытаетесь сохранить файл
int
в формате,List<Integer>
компилятор Java автоматически преобразует его в файлInteger
.источник
На самом деле это не ограничение, не так ли?
Подумайте, хотите ли вы создать коллекцию, в которой хранятся примитивные значения. Как бы вы написали коллекцию, которая может хранить либо int, либо float, либо char? Скорее всего, у вас будет несколько коллекций, поэтому вам понадобятся intlist, charlist и т. Д.
Воспользовавшись объектно-ориентированной природой Java, когда вы пишете класс коллекции, он может хранить любой объект, поэтому вам нужен только один класс коллекции. Эта идея, полиморфизм, очень мощна и значительно упрощает дизайн библиотек.
источник
Я думаю, мы могли бы увидеть прогресс в этой области в JDK, возможно, в Java 10, основанном на этом JEP - http://openjdk.java.net/jeps/218 .
Если вы хотите избежать использования примитивов бокса в коллекциях сегодня, есть несколько сторонних альтернатив. В дополнение к ранее упомянутым сторонним опциям есть также Eclipse Collections , FastUtil и Koloboke .
Некоторое время назад было опубликовано сравнение примитивных карт под названием: Обзор большой HashMap: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . Библиотека GS Collections (Goldman Sachs) была перенесена в Eclipse Foundation и теперь называется Eclipse Collections.
источник
Основная причина - стратегия дизайна Java. ++ 1) коллекции требуют объектов для манипулирования, а примитивы не являются производными от объекта, поэтому это может быть другой причиной. 2) примитивные типы данных Java не являются ссылочным типом, например. int не является объектом.
Преодолеть: -
у нас есть концепция автоматической упаковки и автоматической распаковки. поэтому, если вы пытаетесь сохранить примитивные типы данных, компилятор автоматически преобразует их в объект этого примитивного класса данных.
источник