Content deleted Content added
Giraffedata (talk | contribs) remove overly vague example; a good example is already here. |
Alternate name |
||
(40 intermediate revisions by 23 users not shown) | |||
Line 1:
{{Short description|Programming language concept}}
{{redirect|Object type|another use|Class (computer programming)|the universal type|any type}}
{{
In [[computer science]], '''boxing''' (a.k.a. wrapping) is the transformation of placing a primitive type within an [[Object (computer science)|object]] so that the value can be used as a [[reference type|reference]]. '''Unboxing''' is the reverse transformation of extracting the primitive value from its wrapper object. '''Autoboxing''' is the term for automatically applying boxing and/or unboxing transformations as needed.
==Boxing==▼
Boxing's most prominent use is in [[Java (programming language)|Java]] where there is a distinction between [[reference type|reference]] and [[value type]]s for reasons such as runtime efficiency and syntax and semantic issues. In Java, a {{Java|LinkedList}} can only store values of type {{Java|Object}}. One might desire to have a {{Java|LinkedList}} of {{Java|int}}, but this is not directly possible. Instead Java defines [[primitive wrapper class]]es corresponding to each [[primitive data type|primitive type]]: {{Java|Integer}} and {{Java|int}}, {{Java|Character}} and {{Java|char}}, {{Java|Float}} and {{Java|float}}, etc. One can then define a {{Java|LinkedList}} using the boxed type {{Java|Integer}} and insert {{Java|int}} values into the list by boxing them as {{Java|Integer}} objects. (Using [[generic programming|generic]] parameterized types introduced in [[Java Platform, Standard Edition|J2SE]] 5.0, this type is represented as {{Java|LinkedList<Integer>}}.)
On the other hand, [[C Sharp (programming language)|C#]] has no primitive wrapper classes, but allows boxing of any value type, returning a generic {{C sharp|Object}} reference. In [[Objective-C]], any primitive value can be prefixed by a {{ObjC|@}} to make an {{ObjC|NSNumber}} out of it (e.g. {{ObjC|@123}} or {{ObjC|@(123)}}). This allows for adding them in any of the standard collections, such as an {{ObjC|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.<ref>{{cite web |title=7.2. Unboxed types and primitive operations |url=https://downloads.haskell.org/~ghc/6.12.1/docs/html/users_guide/primitives.html |website=downloads.haskell.org |access-date=10 August 2022}}</ref>
▲==Boxing==
The boxed object is always a copy of the value object, and is usually [[
▲On the other hand, [[C Sharp (programming language)|C#]] has no primitive wrapper classes, but allows boxing of any value type, returning a generic {{C sharp|Object}} reference.
▲The boxed object is always a copy of the value object, and is usually [[Immutable object|immutable]]. Unboxing the object also returns a copy of the stored value. Note that repeated boxing and unboxing of objects can have a severe performance impact, since it [[Dynamic memory allocation|dynamically allocates]] new objects and then makes them eligible for [[Garbage collection (computer science)|Garbage collection]].
▲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.
Autoboxing is the term for getting a reference type out of a value type just through [[type conversion]] (either implicit or explicit). The compiler automatically supplies the extra source code
▲===Autoboxing===
▲Autoboxing is the term for getting a reference type out of a value type just through [[type conversion]] (either implicit or explicit). The compiler automatically supplies the extra source code which creates the object.
For example, in versions of Java prior to J2SE 5.0, the following code did not compile:
<
Integer i = new Integer(9);
Integer i = 9; // error in versions prior to 5.0!
</syntaxhighlight>
Compilers prior to 5.0 would not accept the last line. {{Java|Integer}}
Another example: J2SE 5.0 allows the programmer to treat a collection (such as a {{Java|LinkedList}}) as if it contained
===
For example, in versions of Java prior to J2SE 5.0, the following code did not compile:
<
Integer k = new Integer(4);
int l = k.intValue(); // always
int m = k; // would have been an error, but okay now
</syntaxhighlight>
C# doesn't support automatic unboxing in the same meaning as Java,
In both languages, automatic boxing does not downcast automatically, i.e. the following code won't compile:
C#:
<
int i = 42;
object o = i; // box
int j = o; // unbox (
Console.WriteLine(j); // unreachable line, author might have expected output "42"
</syntaxhighlight>
Java:
<
int i = 42;
Object o = i; // box
int j = o; // unbox (
System.out.println(j); // unreachable line, author might have expected output "42"
</syntaxhighlight>
== Boxing in Rust ==
[[Rust (programming language)|Rust]] has the {{Code|Box}} type, which represents a uniquely owned, heap-allocated value:<ref>{{cite web |title=std::boxed - Rust |url=https://doc.rust-lang.org/std/boxed/index.html |website=doc.rust-lang.org |access-date=2 June 2025}}</ref>
<syntaxhighlight lang="rust">
let number: Box<i32> = Box::new(42);
</syntaxhighlight>
If the value needs to have shared ownership (e.g. between threads), one can use {{Code|Arc}}, which represents a reference-counted, heap-allocated value.<ref>{{cite web |title=Arc in std::sync - Rust |url=https://doc.rust-lang.org/std/sync/struct.Arc.html |website=doc.rust-lang.org |access-date=18 January 2025}}</ref><ref>{{cite web |title=Arc - Rust By Example |url=https://doc.rust-lang.org/rust-by-example/std/arc.html |website=doc.rust-lang.org |access-date=18 January 2025}}</ref>
==Type helpers==
Modern [[Object Pascal]] has yet another way to perform operations on simple types, close to boxing, called type helpers in [[FreePascal]] or record helpers in [[Delphi (programming language)|Delphi]] and [[FreePascal]] in Delphi mode.<br>
The dialects mentioned are Object Pascal compile-to-native languages, and so miss some of the features that C# and Java can implement. Notably run-time [[type inference]] on strongly typed variables.<br>
But the feature is related to boxing.<br>
It allows the programmer to use constructs like
<syntaxhighlight lang="pascal">
{$ifdef fpc}{$mode delphi}{$endif}
uses sysutils; // this unit contains wraps for the simple types
var
x:integer=100;
s:string;
begin
s:= x.ToString;
writeln(s);
end.
</syntaxhighlight>
==References==
{{
{{Data types}}
[[Category:Data types]]
[[Category:Java (programming language)]]
[[Category:Programming language
|