1 de febrero de 2008

Auto-Boxing

Desde Java 5, existe una característica denominada como: Auto-Boxing. Algo asi como un auto-empacador (dejemoslo en auto-boxing) suena mejor, no?. Mejor veamos un ejemplo de como funciona. Antes de Java 5, si se quería utilizar una clase "Wrapper" (Integer, Double, Long, etc...), durante la ejecución, se necesitaba aplicar operaciones matemáticas sobre el objeto "wrapper", era necesario algo asi:

Integer y = new Integer(567); // Crear el objeto
// Muchas lineas de código aquí....
int x = y.intValue(); // Obtener su valor numérico...
x+=1550; // Realizar operación matemática...
y = new Integer(x); // Volverlo a guardar en la variable
System.out.println("y = " + y); // Imprimir por pantalla


Sin embargo, con las ventajas otorgadas por auto-boxing, ahora simplemente hacemos esto:

Integer y = new Integer(567); // Creamos el objeto
y+=1550; // Implicitamente se obtiene el valor, realiza la operación, y se guarda de nuevo en el objeto
System.out.println("y = " + y); // Imprimir por pantalla

Ambos ejemplos,si mi cabeza no me falla dan como resultado:
y = 2117

Apesar de que vemos que al objeto tipo Integer se le esta aplicando una suma directamente, en realidad el compilador hace los mismos pasos que en el ejemplo de arriba. simplemente es una cuestión de conveniencia para facilidad del desarrollador.

Una particularidad que tienen los objetos Wrapper (Long, INteger, Float, etc...) es que por cuestiones de ahorro en memoria, dos instancias de los siguientes objetos serán iguales. (Es decir pasaran el test '==') cuando sus valores sean iguales, para los siguientes casos:

- Boolean (todos)
- Byte (todos)
- Character(desde 'u0000' hasta 'u007f') (7f es 127 en el sistema decimal)
- Short & Integer (desde -128 hasta 127)

Es decir, si tenemos:

Integer n1 = 100;
Integer n2 = 100;
System.out.println(n1.equals(n2));
System.out.println(n1==n2);

El resultado será:

true
true

Pero, si cambiamos los valores a:

Integer n1 = 150;
Integer n2 = 150;
System.out.println(n1.equals(n2));
System.out.println(n1==n2);

El resultado será:

true
false

Volviendo al tema de Auto-Boxing, una de las mayores utilidades de este es al utilizarlo en Colecciones, por ejemplo:

Antes (Java 1.4):


int valor=852
//Mucho código, que procesa la variable valor, va aqui
ArrayList numeros = new ArrayList();
numeros.add(new Integer(valor));


Ahora (Java 5 y posterior)

int valor=852
//Mucho código, que procesa la variable valor, va aqui
ArrayList<Integer> numeros = new ArrayList<Integer>();
numeros.add(valor);

Aparentemente no es mucho el ahorro, pero si manejas constantemente operaciones entre objetos y primitivos, seguro se notará la diferencia. Por último, si te ha extrañado la diferencia de sintaxis para el ArrayList entre las 2 versiones de Java, no os preocupéis, es un cambio implementado también en Java 5, se llama Generics y será el tema de mi proximo post.

No hay comentarios.: