Articulo de referencia

Boxeo (programación informática)

En informática , el empaquetado (también conocido como envoltura) consiste en colocar un tipo primitivo dentro de un objeto para que su valor pueda usarse como referencia . El d...

En informática , el empaquetado (también conocido como envoltura) consiste en colocar un tipo primitivo dentro de un objeto para que su valor pueda usarse como referencia . El desempaquetado es la transformación inversa, que consiste en extraer el valor primitivo de su objeto contenedor. El autoempaquetado se refiere a la aplicación automática de las transformaciones de empaquetado y/o desempaquetado según sea necesario.

Boxeo

El uso más destacado del boxing se encuentra en Java, donde existe una distinción entre tipos de referencia y de valor por razones como la eficiencia en tiempo de ejecución y cuestiones sintácticas y semánticas. En Java, un debe ser tal que sea una instancia de . Se podría desear tener un , pero esto no es directamente posible. En cambio, Java define clases envoltorio primitivas correspondientes a cada tipo primitivo : y , y , y , etc. Usando tipos parametrizados genéricos introducidos en J2SE 5.0, se puede definir un e insertar valores en la lista encapsulándolos como objetos.LinkedList<T>TObjectLinkedList<int>IntegerintCharactercharFloatfloatLinkedList<Integer>intInteger

Por otro lado, C# no tiene clases contenedoras primitivas, pero permite el empaquetado de cualquier tipo de valor, devolviendo una Objectreferencia genérica. En Objective-C , cualquier valor primitivo puede ir precedido de un @para convertirlo NSNumberen un (por ejemplo, @123o ). Esto permite agregarlos a cualquiera de las colecciones estándar, como un .@(123)NSArray

Haskell tiene poca o ninguna noción de tipo de referencia , pero aún utiliza el término "encapsulado" para la representación uniforme de unión etiquetada de puntero a elemento del sistema de tiempo de ejecución . [ 1 ]

El objeto empaquetado siempre es una copia del objeto de valor y, por lo general, es inmutable . Al desempaquetar el objeto, también se devuelve una copia del valor almacenado. El empaquetado y desempaquetado repetido de objetos puede tener un impacto significativo en el rendimiento, ya que el empaquetado asigna dinámicamente nuevos objetos y el desempaquetado (si el valor empaquetado ya no se utiliza) los hace aptos para la recolección de basura . Sin embargo, los recolectores de basura modernos, como el recolector de basura predeterminado Java HotSpot, pueden recolectar de manera más eficiente los objetos de corta duración, por lo que si los objetos empaquetados son de corta duración, el impacto en el rendimiento podría no ser grave.

En algunos lenguajes, existe una equivalencia directa entre un tipo primitivo sin encapsular y una referencia a un tipo de objeto inmutable encapsulado. De hecho, es posible sustituir todos los tipos primitivos de un programa por tipos de objeto encapsulados. Mientras que la asignación de un tipo primitivo a otro copia su valor, la asignación de una referencia a un objeto encapsulado a otra copia el valor de la referencia para que apunte al mismo objeto que la primera referencia. Sin embargo, esto no causa ningún problema, ya que los objetos son inmutables, por lo que semánticamente no hay diferencia real entre dos referencias al mismo objeto o a objetos diferentes (a menos que se considere la igualdad física). Para todas las operaciones distintas de la asignación, como las aritméticas, de comparación y los operadores lógicos, se puede desempaquetar el tipo encapsulado, realizar la operación y volver a encapsular el resultado según sea necesario. Por lo tanto, es posible no almacenar tipos primitivos en absoluto.

Autoboxing

El autoboxing es el término que se utiliza para obtener un tipo de referencia a partir de un tipo de valor mediante una simple conversión de tipo (implícita o explícita). El compilador proporciona automáticamente el código fuente adicional necesario para crear el objeto.

Por ejemplo, en versiones de Java anteriores a J2SE 5.0, el siguiente código no compilaba:

Integer i = new Integer ( 9 ); Integer i = 9 ; // ¡Error en versiones anteriores a la 5.0!

Los compiladores anteriores a la versión 5.0 no aceptaban la última línea. son objetos de referencia, en la superficie no diferentes de , , etc. Para convertir de un a un , había que instanciar "manualmente" el objeto Integer. A partir de J2SE 5.0, el compilador aceptará la última línea y la transformará automáticamente para que se cree un objeto Integer para almacenar el valor . [ 2 ] Esto significa que, a partir de J2SE 5.0, algo como , donde y son ellos mismos, compilará ahora: a y b se desempaquetan, los valores enteros se suman y el resultado se empaqueta automáticamente en un nuevo , que finalmente se almacena dentro de la variable . Los operadores de igualdad no se pueden usar de esta manera, porque los operadores de igualdad ya están definidos para tipos de referencia, para la igualdad de las referencias; para probar la igualdad del valor en un tipo empaquetado, todavía hay que desempaquetarlos manualmente y comparar las primitivas, o usar el método.IntegerListObjectintInteger9Integerc=a+babIntegerIntegercObjects.equals

Otro ejemplo: J2SE 5.0 permite al programador tratar una colección (como una ) como si contuviera valores en lugar de objetos. Esto no contradice lo dicho anteriormente: la colección sigue conteniendo solo referencias a objetos dinámicos y no puede listar tipos primitivos. No puede ser una , sino que debe ser una . Sin embargo, el compilador transforma automáticamente el código para que la lista reciba objetos "silenciosamente", mientras que el código fuente solo menciona valores primitivos. Por ejemplo, el programador ahora puede escribir y pensar como si se añadieran a la lista; pero, el compilador habrá transformado la línea en .LinkedListintIntegerLinkedList<int>LinkedList<Integer>list.add(3)int3list.add(newInteger(3))

Desempaquetado automático

Con el desempaquetado automático, el compilador proporciona automáticamente el código fuente adicional que recupera el valor de ese objeto, ya sea invocando algún método en ese objeto o por otros medios.

Por ejemplo, en versiones de Java anteriores a J2SE 5.0, el siguiente código no compilaba:

Integer k = new Integer ( 4 ); int l = k.intValue (); // siempre está bien int m = k ; // habría sido un error, pero ahora está bien

C# no admite el desempaquetado automático en el mismo sentido que Java, porque no tiene un conjunto separado de tipos primitivos y tipos de objeto. Todos los tipos que tienen versiones tanto primitivas como de objeto en Java, son implementados automáticamente por el compilador de C# como tipos primitivos (de valor) o tipos de objeto (de referencia).

En ambos lenguajes, el boxing automático no realiza la conversión descendente automáticamente, es decir, el siguiente código no compilará:

DO#:

int i = 42 ; object o = i ; // box int j = o ; // unbox (error) Console.WriteLine ( j ) ; // línea inalcanzable, el autor podría haber esperado la salida "42 "

Java:

int i = 42 ; Object o = i ; // box int j = o ; // unbox (error) System.out.println ( j ) ; // línea inalcanzable, el autor podría haber esperado la salida " 42 "

Boxeo en óxido

Rust tiene el Boxtipo, que representa un valor asignado en el montón y de propiedad única: [ 3 ]

let number : Box < i32 > = Box :: new ( 42 );

std::boxed::BoxEn Rust es equivalente a std::unique_ptren C++ , una especie de puntero inteligente .

usando std :: unique_ptr ;unique_ptr < int > number = std :: make_unique < int > ( 42 );

Si el valor necesita tener propiedad compartida (por ejemplo, entre subprocesos), se puede usar Arc, que representa un valor asignado en el montón con conteo de referencias. [ 4 ] [ 5 ] Esto es similar a std::shared_ptren C++.

Ayudantes de tipo

El moderno Object Pascal tiene otra forma de realizar operaciones en tipos simples, similar al boxing, llamada ayudantes de tipo en FreePascal o ayudantes de registro en Delphi y FreePascal en modo Delphi. Los dialectos mencionados son lenguajes de Object Pascal que se compilan a nativo, por lo que carecen de algunas de las características que C# y Java pueden implementar. En particular, la inferencia de tipos en tiempo de ejecución en variables fuertemente tipadas. Pero la característica está relacionada con el boxing. Permite al programador usar construcciones como

{$ifdef fpc}{$mode delphi}{$endif} usa sysutils ; // esta unidad contiene envolturas para los tipos simples var x : integer = 100 ; s : string ; begin s := x.ToString ; writeln ( s ) ; end .

Referencias

  1. "7.2. Tipos sin empaquetar y operaciones primitivas" . downloads.haskell.org . Consultado el 10 de agosto de 2022 .
  2. Entrada de la guía del lenguaje Java de oracle.com sobre autoboxing
  3. "std::boxed - Rust" . doc.rust-lang.org . Consultado el 2 de junio de 2025 .
  4. "Arc en std::sync - Rust" . doc.rust-lang.org . Consultado el 18 de enero de 2025 .
  5. "Arc - Rust By Example" . doc.rust-lang.org . Consultado el 18 de enero de 2025 .