Ответ 1
С# имеет систему унифицированного типа. Все типы С#,, включая примитивные типы, такие как int и double, наследуются от одного корневого object
типа. В отличие от объектов класса эти примитивные типы являются типами значений. Они не выделяются отдельно, а они передаются по значению.
Когда тип значения С# (такой как примитивный int или определяемая пользователем структура) помещается в параметрический набор, он сохраняется в массиве с плотной упаковкой без указателей. Это возможно, потому что С# создает настраиваемый параметрический экземпляр для каждого различного параметрического "размера", который требуется. Это означает, что когда вы создаете экземпляр С# List<int>
, список базового массива хранит массивы с плотной упаковкой int.
Источник: http://www.pin5i.com/showtopic-24376.html
Java также имеет несколько примитивных типов (int, long, double, byte и т.д.) - однако они отличаются тем, что они ориентированных, и они не могли быть определены с использованием самого языка. Они представляют собой типы значений, а не кучу, выделенные и переданные по значению.
Источник: Сравнение системы С# и Java - Унифицированного типа (Википедия)
В то же время Java также имеет объектно-ориентированные примитивные типы "обертки" (Integer, Long, Double, Byte и т.д.), которые часто называются типами boxed
. Это кучи выделенных объектов, которые передаются по ссылке, и существуют параллельно с примитивными типами, упомянутыми выше.
В более поздних версиях Java примитивные типы автоматически вставляются в типы объектов, когда это необходимо. Это облегчает большую часть управления ими, но также может вызывать тонкие ошибки (см. Также авто-бокс).
В отличие от С#, в Java встроенная структура JDK Collections всегда управляет коллекциями указателей объектов. Чтобы сделать их параметрическими с обратной совместимостью, Java выполняет метод, называемый стиранием стилей, где (во время выполнения) все рассматривается как объект внутри контейнера (параметрированные проверки типов выполняются во время компиляции).
Это означает, что вы не можете создать Java List<int>
, вы можете сделать только List<Integer>
. И в приведенном выше списке на самом деле хранится массив указателей на объекты с коротким Integer
, который вдвое больше размера и существенно менее эффективен, чем версия С#. Для большинства случаев это различие в размере и производительности не имеет значения.
В случаях, когда размер и производительность имеют значение, доступны два варианта:
- Когда вы заранее знаете размер своего списка, используйте массив собственных типов, например
int[]
. Массивы собственных типов упакованы в память, поэтому они потребляют меньше памяти и более эффективны. - Если вы не знаете размер своего списка заранее, используйте некоторую реализацию стороннего списка, которая обертывает собственный массив, что позволяет добавлять к нему элементы после создания (некоторые примеры: Trove, Colt, Fastutil, Guava).