что такое боксинг и анбоксинг

Упаковка-преобразование и распаковка-преобразование (Руководство по программированию на C#)

Упаковка представляет собой процесс преобразования типа значения в тип object или в любой другой тип интерфейса, реализуемый этим типом значения. Когда тип значения упаковывается общеязыковой средой выполнения (CLR), он инкапсулирует значение внутри экземпляра System.Object и сохраняет его в управляемой куче. Операция распаковки извлекает тип значения из объекта. Упаковка является неявной; распаковка является явной. Понятия упаковки и распаковки лежат в основе единой системы типов C#, в которой значение любого типа можно рассматривать как объект.

Затем можно выполнить операцию распаковки объекта o и присвоить его целочисленной переменной i :

Следующий пример иллюстрирует использование упаковки в C#.

Производительность

По сравнению с простыми операциями присваивания операции упаковки и распаковки являются весьма затратными процессами с точки зрения вычислений. При выполнении упаковки типа значения необходимо создать и разместить новый объект. Объем вычислений при выполнении операции распаковки, хотя и в меньшей степени, но тоже весьма значителен. Дополнительные сведения см. в разделе Производительность.

Упаковка

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

Рассмотрим следующее объявление переменной типа значения.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

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

Пример

Распаковка

Распаковка является явным преобразованием из типа object в тип значения или из типа интерфейса в тип значения, реализующего этот интерфейс. Операция распаковки состоит из следующих действий:

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

копирование значения из экземпляра в переменную типа значения.

В следующем коде показаны операции по упаковке и распаковке.

На рисунке ниже представлен результат выполнения этого кода.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Для успешной распаковки типов значений во время выполнения необходимо, чтобы экземпляр, который распаковывается, был ссылкой на объект, предварительно созданный с помощью упаковки экземпляра этого типа значения. Попытка распаковать null создает исключение NullReferenceException. Попытка распаковать ссылку на несовместимый тип значения создает исключение InvalidCastException.

Пример

При выполнении этой программы выводится следующий результат:

Specified cast is not valid. Error: Incorrect unboxing.

При изменении оператора:

будет выполнено преобразование со следующим результатом:

Спецификация языка C#

Дополнительные сведения см. в спецификации языка C#. Спецификация языка является предписывающим источником информации о синтаксисе и использовании языка C#.

Источник

Что такое упаковка и распаковка(boxing/unboxing)?

Что это вообще такое упаковка и распаковка (boxing/unboxing) и зачем она нужна?

Был бы рад примерам.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

3 ответа 3

их нельзя помещать в коллекции и прочее.

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

В тех случаях, когда по контексту требуются объекты (присваивание, вызов метода с передачей параметров), а мы используем значения примитивных типов (переменные или выражения типа 2 * 3), всегда происходит автоупаковка.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

В версиях ниже JDK 1.5 было не легко преобразовывать примитивные типы данных, такие как int, char, float, double в их классы оболочки Integer, Character, Float, Double. Начиная с версии JDK 5 эта функция, преобразования примитивных типов в эквивалентные объекты, реализована автоматически. Это свойство известно как Автоупаковка(Autoboxing). Обратный процесс соответственно – Распаковка(Unboxing) т.е. процесс преобразования объектов в соответствующие им примитивные типы.

Пример кода для автоупаковки и распаковки представлен ниже:

Когда используется автоупаковка и распаковка?

Автоупаковка применяется компилятором Java в следующих условиях:

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Всё ещё ищете ответ? Посмотрите другие вопросы с метками java java-faq или задайте свой вопрос.

Связанные

Похожие

Подписаться на ленту

Для подписки на ленту скопируйте и вставьте эту ссылку в вашу программу для чтения RSS.

дизайн сайта / логотип © 2021 Stack Exchange Inc; материалы пользователей предоставляются на условиях лицензии cc by-sa. rev 2021.11.12.40742

Нажимая «Принять все файлы cookie» вы соглашаетесь, что Stack Exchange может хранить файлы cookie на вашем устройстве и раскрывать информацию в соответствии с нашей Политикой в отношении файлов cookie.

Источник

BestProg

Упаковка и распаковка. Необходимость (преимущества) применения обобщений. Повышение типовой безопасности с помощью обобщений

Содержание

Поиск на других ресурсах:

1. Понятие упаковки (boxing) и распаковки (unboxing)

Допускается также использовать переменную типа object в правой части оператора присваивания:

Но в этом случае нужно указывать явное приведение типов, как видно из строки

иначе будет ошибка на этапе компиляции.

Если переменная типа object используется в левой части оператора присваивания, то компилятор выполняет так называемую упаковку. Если переменная или значение типа object используется в правой части оператора присваивания, то компилятор выполняет распаковку.

Использование обобщений вместо использования типа object дает следующие преимущества:

В следующих пунктах эти преимущества рассматриваются более подробно.

2.1. Преимущество 1. Отсутствие явного приведения типа

Если используется обобщение, то не нужно выполнять явное приведение типов в операции присваивания как показано на рисунке 1.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Рисунок 1. Отличие в явном приведении к типу int между обобщением и типом object

2.2. Преимущество 2. Обеспечение типовой безопасности в обобщениях

При использовании класса object в качестве типа можно допустить ошибку, которая на этапе компиляции не будет обнаружена. Эта ошибка окажется на этапе выполнения, что неприемлемо.

В случае с классом ObjectClass ошибки на этапе компиляции не возникает. Эта ошибка вызовет исключительную ситуацию на этапе выполнения.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Рисунок 2. Особенности выявления ошибки компилятором для обобщенного и необобщенных класса

2.3. Преимущество 3. Повышение производительности

Использование обобщенных классов дает большую производительность (быстродействие) по сравнению с необобщенными. При присвоении значения типа object другим типам и наоборот, компилятор выполняет упаковку и распаковку (смотрите п. 1). Этот процесс требует больше временных затрат чем использование обобщений. В случае с обобщениями формируется типизированный код с привязкой к конкретному типу, который выполняется быстрее.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Источник

Boxing и unboxing — что быстрее?

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Код примера доступен на github, поэтому приглашаю всех желающих сообщить о своих результатах измерений в комментариях.

Теория

Операция упаковки boxing характеризуется выделением памяти в управляемой куче (managed heap) под объект value type и дальнейшее присваивание указателя на этот участок памяти переменной в стеке.

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

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

Как заметил blanabrother в комментариях, при выделении памяти/копировании значения в managed heap отсутствует процесс поиска свободного участка памяти и её возможная фрагментация ввиду инкриминирующегося указателя и дальнейшей её компактификации с использованием GC. Однако, опираясь на следующие измерения скорости выделения памяти в C++ посмею предположить, что область (тип) памяти является основной причиной такой разницы в производительности.

В случае же с распаковкой, память выделяется в стеке выполнения, который содержит указатель на свой конец, по совместительству являющийся началом участка памяти под новый объект.

Вывод из этого я делаю такой, что процесс упаковки должен занимать значительно больше времени, чем распаковки, ввиду возможных side effects связанных с GC и медленной скоростью выделения памяти/копирования значения в managed heap.

Практика

Для проверки этого утверждения я набросал 4 небольшие функции: 2 для boxing и 2 для unboxing типов int и struct.

Для замера производительности была использована библиотека BenchmarkDotNet в режиме Release (буду рад если DreamWalker подскажет, каким образом сделать данные замеры более объективными). Далее представлен результат измерений:

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Сразу оговорюсь, что не могу быть твёрдо уверен в отсутствии оптимизаций компилятором итогового кода, однако, судя по IL коду, каждая из функций содержит проверяемую операцию в единственном числе.

Измерения проводились на нескольких машинах с разным кол-вом LoopCount, однако, скорость распаковки из раза в раз превосходила упаковку в 3-8 раз.

Источник

Какой смысл в boxing/unboxing?

Иногда есть необходимость работать с чем то обобщенным, абстрагироваться от конкретного типа. Например при сериализации в json для отправки данных клиенту, как то так

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

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

Смотрите это как на инструмент, вытекающий из механизма ООП(а точнее наследования) в языке C#.

Вот цитата из довольно развёрнутого ответа на такой же вопрос:
Источник цитаты

Подумайте об этом так. У вас есть переменная o типа object. И теперь у вас есть int, и вы хотите поместить его в o. o является ссылкой на что-то где-то, а int категорически не является ссылкой на что-то где-то (в конце концов, это просто число). Итак, что вы делаете, так это: вы создаете новый object, который может хранить int, а затем вы назначаете ссылку на этот объект на o. Мы называем этот процесс «боксом».

Итак, если вам не нужно иметь унифицированную систему типов (т.е. ссылочные типы и типы значений имеют очень разные представления, и вам не нужен общий способ «представить» эти два), то вы не нужен бокс. Если вам не нужно, чтобы int представляло их базовое значение (т.е. Вместо этого int тоже были ссылочными типами и просто сохраняли ссылку на их базовое значение), вам не нужен бокс.

что такое боксинг и анбоксинг. Смотреть фото что такое боксинг и анбоксинг. Смотреть картинку что такое боксинг и анбоксинг. Картинка про что такое боксинг и анбоксинг. Фото что такое боксинг и анбоксинг

To have a unified type system and allow value types to have a completely different representation of their underlying data from the way that reference types represent their underlying data (e.g., an int is just a bucket of thirty-two bits which is completely different than a reference type).

Think of it like this. You have a variable «o» of type object. And now you have an int and you want to put it into «o». «o» is a reference to something somewhere, and the int is emphatically not a reference to something somewhere (after all, it’s just a number). So, what you do is this: you make a new object that can store the int and then you assign a reference to that object to «o». We call this process «boxing.»

So, if you don’t care about having a unified type system (i.e., reference types and value types have very different representations and you don’t want a common way to «represent» the two) then you don’t need boxing. If you don’t care about having int represent their underlying value (i.e., instead have int be reference types too and just store a reference to their underlying value) then you don’t need boxing.

Where should I use it.

For example, the old collection type ArrayList only eats objects. That is, it only stores references to somethings that live somewhere. Without boxing you cannot put an int into such a collection. But with boxing, you can.

Now, in the days of generics you don’t really need this and can generally go merrily along without thinking about the issue.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *