En informática , un tipo de objeto (también conocido como objeto envolvente ) es un tipo de datos que se utiliza en la programación orientada a objetos para envolver un tipo que no es de objeto para que parezca un objeto dinámico . [ cita requerida ]
Algunos lenguajes de programación orientados a objetos hacen una distinción entre tipos de valores y de referencia , a menudo denominados objetos y no objetos en plataformas donde no existen tipos de valores complejos, por razones como la eficiencia del tiempo de ejecución y problemas de sintaxis o semánticos. Por ejemplo, Java tiene clases contenedoras primitivas correspondientes a cada tipo primitivo : y , y , y , etc. Los lenguajes como C ++ tienen poca o ninguna noción de tipo de referencia ; por tanto, el uso del tipo de objeto tiene poco interés.Integer
int
Character
char
Float
float
Boxeo
El encajonamiento, también conocido como envoltura, es el proceso de colocar un tipo primitivo dentro de un objeto para que el primitivo pueda usarse como objeto de referencia. Por ejemplo, en Java, a LinkedList
puede cambiar su tamaño, pero una matriz debe tener un tamaño fijo. Uno podría desear tener un LinkedList
of int
, pero la LinkedList
clase solo enumera referencias a objetos dinámicos; no puede enumerar tipos primitivos, que son tipos de valor.
Para evitar esto, int
se pueden encajonar Integer
, que son objetos dinámicos, y luego agregarlos a un LinkedList
de Integer
. (Utilizando tipos genéricos parametrizados introducidos en J2SE 5.0, este tipo se representa como .) Por otro lado, C # no tiene clases contenedoras primitivas, pero permite el recuadro de cualquier tipo de valor, devolviendo una referencia genérica . En Objective-C , cualquier valor primitivo puede tener el prefijo a para convertirlo en una (por ejemplo, o ). Esto permite agregarlos en cualquiera de las colecciones estándar, como un .LinkedList<Integer>
Object
@
NSNumber
@123
@(123)
NSArray
El objeto en caja es siempre una copia del objeto de valor y, por lo general, es inmutable . Desembalar el objeto también devuelve una copia del valor almacenado. El empaquetado y desempaquetado repetido de objetos puede tener un impacto severo en el rendimiento, porque el empaquetado asigna dinámicamente nuevos objetos y el desempaquetado (si el valor en caja ya no se usa) los hace elegibles para la recolección de basura . Sin embargo, los recolectores de basura modernos, como el recolector de basura Java HotSpot predeterminado, pueden recolectar objetos de corta duración de manera más eficiente, por lo que si los objetos en caja son de corta duración, el impacto en el rendimiento puede no ser tan malo.
En algunos lenguajes, existe una equivalencia directa entre un tipo primitivo sin caja y una referencia a un tipo de objeto en caja inmutable. De hecho, es posible sustituir todos los tipos primitivos en un programa con tipos de objetos en caja. Mientras que la asignación de una primitiva a otra copiará su valor, la asignación de una referencia a un objeto en caja a otro copiará el valor de referencia para hacer referencia al mismo objeto que la primera referencia. Sin embargo, esto no causará ningún problema, porque los objetos son inmutables, por lo que semánticamente no hay una diferencia real entre dos referencias al mismo objeto oa diferentes objetos (a menos que mires la igualdad física). Para todas las operaciones distintas de la asignación, como los operadores aritméticos, de comparación y lógicos, se puede desempaquetar el tipo en caja, realizar la operación y volver a enmarcar el resultado según sea necesario. Por tanto, es posible no almacenar tipos primitivos en absoluto.
Autoboxing
Autoboxing es el término para obtener un tipo de referencia de un tipo de valor simplemente mediante la conversión de tipos (ya sea implícita o explícita). El compilador proporciona automáticamente el código fuente adicional que crea el objeto.
Por ejemplo, en las versiones de Java anteriores a J2SE 5.0, el siguiente código no se compilaba:
Entero i = nuevo Entero ( 9 ); Entero i = 9 ; // ¡error en versiones anteriores a la 5.0!
Los compiladores anteriores a 5.0 no aceptarían la última línea. Integer
son objetos de referencia, en la superficie no es diferente de List
, Object
y así sucesivamente. Para convertir de an int
a an Integer
, uno tení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 9
. [1] Esto significa que, a partir de J2SE 5.0 , se compilará ahora algo como dónde y están ellos mismos: ayb se desempaquetan, se resumen los valores enteros y el resultado se autoencaja en un nuevo , que finalmente se almacena dentro variable . Los operadores de igualdad no se pueden usar de esta manera, porque los operadores de igualdad ya están definidos para los tipos de referencia, para la igualdad de las referencias; para probar la igualdad del valor en un tipo en caja, aún se deben desempaquetar manualmente y comparar las primitivas, o usar el método.Integer c = a + b
a
b
Integer
Integer
c
Objects.equals
Otro ejemplo: J2SE 5.0 permite al programador tratar una colección (como a LinkedList
) como si contuviera int
valores en lugar de Integer
objetos. Esto no contradice lo dicho anteriormente: la colección todavía solo contiene referencias a objetos dinámicos y no puede enumerar tipos primitivos. No puede ser un , pero debe ser un en su lugar. 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 .LinkedList<int>
LinkedList<Integer>
list.add(3)
int
3
list.add(new Integer(3))
Desembalaje
Unboxing se refiere a obtener el valor que está asociado a un objeto dado, simplemente a través de la conversión de tipos (ya sea implícita o explícita). 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 las versiones de Java anteriores a J2SE 5.0, el siguiente código no se compilaba:
Entero k = nuevo Entero ( 4 ); int l = k . intValue (); // siempre bien int m = k ; // habría sido un error, pero está bien ahora
C # no admite el desempaquetado automático en el mismo significado que Java, porque no tiene un conjunto separado de tipos primitivos y tipos de objetos. Todos los tipos que tienen versiones primitivas y de objeto en Java, son implementados automáticamente por el compilador de C # como tipos primitivos (valor) o tipos de objetos (referencia).
En ambos idiomas, el boxeo automático no se abatió automáticamente, es decir, el siguiente código no se compilará:
C#:
int i = 42 ; objeto o = i ; // recuadro int j = o ; // unbox (error) Consola . WriteLine ( j ); // línea inalcanzable, el autor podría haber esperado la salida "42"
Java:
int i = 42 ; Objeto o = i ; // recuadro int j = o ; // unbox (error) System . fuera . println ( j ); // línea inalcanzable, el autor podría haber esperado la salida "42"
Ayudantes de tipo
Modern Object Pascal tiene otra forma de realizar operaciones en tipos simples, cerca del boxing, llamados ayudantes de tipos en FreePascal o ayudantes de registros en Delphi y FreePascal en modo Delphi.
Los dialectos mencionados son lenguajes nativos de Object Pascal, por lo que se pierden algunas de las características que C # y Java pueden implementar. En particular, la inferencia de tipo en tiempo de ejecución en variables fuertemente tipadas.
Pero la característica está relacionada con el boxeo.
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 : cadena ; comenzar s : = x . ToString ; escrito ( s ) ; final .