Подтвердить что ты не робот

Java: зачем нужны классы-оболочки?

На очень высоком уровне я знаю, что нам нужно "обернуть" примитивные типы данных, такие как int и char, используя их соответствующие классы-оболочки для их использования в коллекциях Java. Я хотел бы понять, как Коллекции Java работают на низком уровне, спрашивая: "Почему нам нужно обернуть примитивные типы данных в качестве объектов, чтобы использовать их в коллекциях?" Я заранее благодарю вас за вашу помощь.

4b9b3361

Ответ 1

На уровне виртуальной машины это потому, что примитивные типы представлены по-разному в памяти по сравнению со ссылочными типами, такими как java.lang.Object и его производные типы. Примитивный int в Java, например, составляет всего 4 байта в памяти, тогда как Object занимает как минимум 8 байтов сам по себе, плюс еще 4 байта для его ссылки. Такой дизайн является простым отражением того факта, что процессоры могут более эффективно обрабатывать примитивные типы.

Итак, один ответ на ваш вопрос "зачем нужны типы обертки" - это из-за улучшения производительности, которое он позволяет.

Но для программистов такое различие добавляет некоторые нежелательные когнитивные накладные расходы (например, не может использовать int и float в коллекциях.) На самом деле, вполне возможно сделать дизайн языка, скрывая это различие --- многие языки сценариев делают это, и CLR делает это. Начиная с 1.5, Java тоже делает это. Это достигается за счет того, что компилятор молча вводит необходимое преобразование между примитивным представлением и представлением Object (которое обычно называют бокс/распаковкой.)

Итак, еще один ответ на ваш вопрос: "Нет, нам это не нужно", потому что компилятор делает это автоматически для вас, и в определенной степени вы можете забыть, что происходит за сценой.

Ответ 2

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

Прочтите эту короткую статью на Autoboxing для получения дополнительной информации.

Если вам нужны подробные подробные сведения, это в значительной степени сводится к следующему:

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

Ответ 3

Чтобы сохранить значения примитивного типа в классах коллекции, нам требуется Wrapper classe.

Ответ 4

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

Ответ 6

Ну, причина в том, что коллекции Java не различают примитив и объект. Он обрабатывает их все как Object, и поэтому ему понадобится обертка. Вы можете легко создать собственный класс коллекции, который не нуждается в оболочке, но в конце вам придется создавать по одному для каждого типа char, int, float, double и т.д., Умножать типы коллекций (Set, Карта, Список, + их реализация).

Можете ли вы представить себе, как это скучно?

И дело в том, что производительность, которую он приносит, без использования обертки, практически не имеет значения для большинства приложений. Однако, если вам нужна очень высокая производительность, некоторые библиотеки для примитивных коллекций также доступны (например, http://www.joda.org/joda-primitives/)

Ответ 7

В коллекции используются Generics. Framework Collection предназначен для сбора, хранения и обработки данных любого класса. Поэтому он использует общий тип. Используя Generics, он может хранить данные ЛЮБОГО КЛАССА, имя которого указано в его объявлении.

Теперь у нас есть различные сценарии, в которых нужно хранить примитивные данные таким же образом, в которых работает коллекция. У нас нет возможности хранить примитивные данные, используя классы Collection, такие как ArrayList, HashSet и т.д., Потому что классы Collection могут хранить только объекты. Таким образом, для хранения примитивных типов в коллекции мы предоставляем классы-оболочки.

Ответ 8

Классы Wrapper предоставляют полезные методы, связанные с соответствующими типами данных, которые вы можете использовать в определенных случаях.

Один простой пример. Рассмотрим это,

Integer x=new Integer(10); 
//to get the byte value of 10
x.byteValue(); 

//but you can't do this,
int x=10;
x.byteValue(); //Wrong!

Вы можете получить точку?

Ответ 9

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

Если Object получен из Anything и объектов класса, полученных из Object, но примитивов, унаследованных от другого класса, полученного из Anything, тогда в 64-битной реализации может быть целесообразно сказать, что о 3/4 возможных битовых шаблонов будут представлять значения double ниже 2 ^ 512, 1/8 из них для представления значений long в диапазоне +/- 1,152,921,504,606,846,975, несколько миллиардов, чтобы представить любую возможную ценность любого другого примитива, и 1/256 для идентификации объектов. Многие виды операций над вещами типа Anything будут медленнее, чем с типом Object, но такие операции не будут ужасно частыми; большинство кода закончили бы литье Anything до более определенного типа, прежде чем пытаться работать с ним; фактический тип, хранящийся в Anything, должен быть проверен перед литой, но не после выполнения трансляции. Тем не менее, при отсутствии различия между переменной, содержащей ссылку на тип кучи, против одного, содержащего "что-либо", не было бы способа избежать существенного расширения служебных данных, чем это было бы иначе или должно быть.

Ответ 10

Как и класс String, Wrappers предоставляют дополнительную функциональность и позволяют программисту сделать немного больше с процессом хранения данных. Таким образом, люди используют класс String, например....

String uglyString = "fUbAr"; String myStr = uglyString.toLower();

так и они могут с помощью Wrapper. Подобная идея.

Это в дополнение к проблеме ввода коллекций/дженериков, упомянутых выше Bharat.

Ответ 11

Прочитайте все ответы, но ни один из них не объясняет это просто в непрофессиональных условиях.

Класс оболочки обертывает (охватывает) вокруг типа данных (может быть любым примитивным типом данных, таким как int, char, byte, long) и делает его объектом.

Вот несколько причин, по которым необходимы классы-оболочки:

  • Разрешает значения null.
  • Может использоваться в коллекции, например List, Map и т.д.
  • Может использоваться в методах, которые принимают аргументы типа Object.
  • Может быть создан как объекты с помощью new ClassName(), как и другие объекты:

    Integer wrapperInt = new Integer("10");
    
  • Делает доступными все функции класса Object, такие как clone(), equals(), hashCode(), toString() и т.д.

Классы Wrapper могут быть созданы двумя способами:

  • Использование конструктора:

    Integer i = new Integer("1"); //new object is created
    
  • Использование valueOf() статических операторов:

     Integer i  = Integer.valueOf("100"); //100 is stored in variable
    

Рекомендуется использовать второй способ создания классов-оболочек, поскольку он занимает меньше памяти, поскольку новый объект не создается.