Введение
Концепция языка программирования
В информатике, боксинг (также известный как упаковка) — это преобразование, заключающееся в размещении примитивного типа внутри объекта, чтобы значение можно было использовать как ссылку. Анбоксинг — это обратное преобразование, извлечение примитивного значения из его объекта-обертки. Автобоксинг — это термин, обозначающий автоматическое применение преобразований боксинга и/или анбоксинга по мере необходимости.
Боксер
Наиболее заметное применение боксинга наблюдается в Java, где существует различие между типами-ссылками и типами-значениями, обусловленное такими факторами, как эффективность выполнения, а также синтаксические и семантические особенности. В Java список может хранить только значения определенного типа, но хотелось бы иметь возможность хранить значения примитивных типов в списке. Вместо этого Java определяет классы-обертки для каждого примитивного типа: `Integer` и `Boolean`, `Float` и `Double`, `Long` и т.д. Тогда можно определить список, используя обобщенный тип-обертку, и вставлять примитивные значения в список, преобразуя их в объекты-обертки (боксинг). (Используя обобщенные параметризованные типы, представленные в J2SE 5.0, этот тип представляется как `List<Integer>`.) С другой стороны, в C# нет классов-оберток для примитивных типов, но допускается боксинг любого типа-значения, возвращающий универсальную ссылку. В Objective-C любое примитивное значение можно снабдить префиксом `*`, чтобы преобразовать его в указатель (например, `*int` или `*float`). Это позволяет добавлять их в любые стандартные коллекции, такие как `NSArray`.
Haskell has little or no notion of reference type, but still uses the term "boxed" for the runtime system's uniform pointer to tagged union representation. The boxed object is always a copy of the value object, and is usually immutable. Unboxing the object also returns a copy of the stored value. Repeated boxing and unboxing of objects can have a severe performance impact, because boxing dynamically allocates new objects and unboxing (if the boxed value is no longer used) then makes them eligible for garbage collection. However, modern garbage collectors such as the default Java HotSpot garbage collector can more efficiently collect short lived objects, so if the boxed objects are short lived, the performance impact may not be severe. In some languages, there is a direct equivalence between an unboxed primitive type and a reference to an immutable, boxed object type. In fact, it is possible to substitute all the primitive types in a program with boxed object types. Whereas assignment from one primitive to another will copy its value, assignment from one reference to a boxed object to another will copy the reference value to refer to the same object as the first reference. However, this will not cause any problems, because the objects are immutable, so there is semantically no real difference between two references to the same object or to different objects (unless you look at physical equality). For all operations other than assignment, such as arithmetic, comparison, and logical operators, one can unbox the boxed type, perform the operation, and re box the result as needed. Thus, it is possible to not store primitive types at all.
В Haskell практически отсутствует понятие типа-ссылки, но термин "boxed" все равно используется для обозначения единообразного указателя системы времени выполнения на представление в виде объединения с тегами. Объект в формате boxing всегда является копией объекта-значения и обычно является неизменяемым. Операция unboxing (распаковка) также возвращает копию хранимого значения. Многократное выполнение операций боксинга и unboxing может существенно снизить производительность, поскольку боксинг динамически выделяет новые объекты, а unboxing (если объект-обертка больше не используется) делает их доступными для сборки мусора. Однако современные сборщики мусора, такие как сборщик мусора Java HotSpot по умолчанию, могут более эффективно собирать объекты с коротким временем жизни, поэтому, если объекты-обертки живут недолго, влияние на производительность может быть незначительным. В некоторых языках существует прямое соответствие между распакованным примитивным типом и ссылкой на неизменяемый объект-обертку. Фактически, можно заменить все примитивные типы в программе на объекты-обертки. В то время как присваивание от одного примитивного типа к другому копирует его значение, присваивание от одной ссылки на объект-обертку к другой копирует значение ссылки, чтобы она указывала на тот же объект, что и первая ссылка. Однако это не вызовет проблем, поскольку объекты неизменяемы, поэтому семантически нет реальной разницы между двумя ссылками на один и тот же объект или на разные объекты (если не рассматривать физическое равенство). Для всех операций, кроме присваивания, таких как арифметические, сравнения и логические операции, можно выполнить unboxing объекта-обертки, выполнить операцию и, при необходимости, снова выполнить боксинг результата. Таким образом, можно вообще не хранить примитивные типы.
Haskell has little or no notion of reference type, but still uses the term "boxed" for the runtime system's uniform pointer to tagged union representation. The boxed object is always a copy of the value object, and is usually immutable. Unboxing the object also returns a copy of the stored value. Repeated boxing and unboxing of objects can have a severe performance impact, because boxing dynamically allocates new objects and unboxing (if the boxed value is no longer used) then makes them eligible for garbage collection. However, modern garbage collectors such as the default Java HotSpot garbage collector can more efficiently collect short lived objects, so if the boxed objects are short lived, the performance impact may not be severe. In some languages, there is a direct equivalence between an unboxed primitive type and a reference to an immutable, boxed object type. In fact, it is possible to substitute all the primitive types in a program with boxed object types. Whereas assignment from one primitive to another will copy its value, assignment from one reference to a boxed object to another will copy the reference value to refer to the same object as the first reference. However, this will not cause any problems, because the objects are immutable, so there is semantically no real difference between two references to the same object or to different objects (unless you look at physical equality). For all operations other than assignment, such as arithmetic, comparison, and logical operators, one can unbox the boxed type, perform the operation, and re box the result as needed. Thus, it is possible to not store primitive types at all.