Clases contenedoras en Java

1. Información general

Como sugiere el nombre, las clases contenedoras son objetos que encapsulan tipos primitivos de Java.

Cada primitiva de Java tiene un contenedor correspondiente:

  • booleano, byte, corto, char, int, largo, flotante, doble
  • Booleano, Byte, Corto, Carácter, Entero, Largo, Flotante, Doble

Todos están definidos en el paquete java.lang , por lo que no es necesario importarlos manualmente.

2. Clases de envoltura

“¿Cuál es el propósito de una clase contenedora?”. Es una de las preguntas de entrevistas de Java más comunes.

Básicamente, las clases genéricas solo funcionan con objetos y no admiten primitivas . Como resultado, si queremos trabajar con ellos, tenemos que convertir valores primitivos en objetos envoltorios.

Por ejemplo, Java Collection Framework funciona exclusivamente con objetos. Hace mucho tiempo cuando (antes de Java 5, hace casi 15 años) no había autoboxing y nosotros, por ejemplo, no podíamos simplemente llamar a add (5) en una colección de Integers.

En ese momento, esos valores primitivos debían convertirse manualmente en las clases contenedoras correspondientes y almacenarse en colecciones.

Hoy, con el autoboxing, podemos hacer ArrayList.add (101) fácilmente, pero internamente Java convierte el valor primitivo en un Integer antes de almacenarlo en ArrayList usando el método valueOf () .

3. Conversión de clase primitiva a envoltura

Ahora la gran pregunta es: ¿cómo convertimos un valor primitivo en una clase contenedora correspondiente, por ejemplo, un int en Integer o un char en Character?

Bueno, podemos usar métodos de constructor o de fábrica estática para convertir un valor primitivo en un objeto de una clase contenedora.

Sin embargo, a partir de Java 9, los constructores de muchas primitivas en caja como Integer o Long han quedado obsoletos.

Por lo tanto , es muy recomendable utilizar solo los métodos de fábrica en el código nuevo .

Veamos un ejemplo de conversión de un valor int en un objeto Integer en Java:

Integer object = new Integer(1); Integer anotherObject = Integer.valueOf(1);

El método valueOf () devuelve una instancia que representa el valor int especificado .

Devuelve valores en caché que lo hacen eficiente. Siempre almacena en caché valores entre -128 y 127, pero también puede almacenar en caché otros valores fuera de este rango.

De manera similar, también podemos convertir booleano a booleano, byte a Byte, char a Character, long a Long, float a Float y double a Double. Aunque si tenemos que convertir String en Integer, entonces necesitamos usar el método parseInt () porque String no es una clase contenedora.

Por otro lado, para convertir de un objeto contenedor a un valor primitivo, podemos usar el método correspondiente como intValue (), doubleValue (), etc.

int val = object.intValue(); 

Puede encontrar una referencia completa aquí.

4. Autoboxing y Unboxing

En la sección anterior, mostramos cómo convertir manualmente un valor primitivo en un objeto.

Después de Java 5, esta conversión se puede realizar automáticamente mediante el uso de funciones llamadas autoboxing y unboxing.

"Boxing" se refiere a convertir un valor primitivo en un objeto de envoltura correspondiente. Debido a que esto puede suceder automáticamente, se conoce como autoboxing.

Del mismo modo, cuando un objeto contenedor se desenvuelve en un valor primitivo, esto se conoce como unboxing.

Lo que esto significa en la práctica es que podemos pasar un valor primitivo a un método que espera un objeto contenedoro asignar una primitiva a una variable que espera un objeto:

List list = new ArrayList(); list.add(1); // autoboxing Integer val = 2; // autoboxing

En este ejemplo, Java convertirá automáticamente el valor int primitivo en el contenedor.

Internamente, utiliza el método valueOf () para facilitar la conversión. Por ejemplo, las siguientes líneas son equivalentes:

Integer value = 3; Integer value = Integer.valueOf(3);

Aunque esto hace que la conversión sea fácil y que los códigos sean más legibles, hay algunos casos en los que no deberíamos usar autoboxing, por ejemplo, dentro de un bucle .

De manera similar al autoboxing, el desempaquetado se realiza automáticamente al pasar un objeto a un método que espera una primitiva o al asignarlo a una variable primitiva:

Integer object = new Integer(1); int val1 = getSquareValue(object); //unboxing int val2 = object; //unboxing public static int getSquareValue(int i) { return i*i; }

Básicamente, si escribimos un método que acepta un valor primitivo o un objeto contenedor, aún podemos pasarles ambos valores. Java se encargará de pasar el tipo correcto, por ejemplo, primitivo o envoltorio según el contexto.

5. Conclusión

En este tutorial rápido, hablamos sobre las clases contenedoras en Java, así como el mecanismo de autoboxing y unboxing.