La respuesta del kit de herramientas anterior es correcta y la mejor manera, pero no proporciona una explicación completa de lo que está sucediendo. Suponiendo Java 5 o posterior:
Integer a = new Integer(2); // or even just Integer a = 2;
a *= 10;
System.out.println(a); // will output 20
Lo que hay que saber es que este es exactamente el mismo que hacer:
Integer a = new Integer(2); // or even just Integer a = 2;
a = a.intValue() * 10;
System.out.println(a.intValue()); // will output 20
Mediante la realización de la operación (en este caso * =) en el objeto 'a', no está cambiando el valor int dentro del objeto 'a', sino que realmente asigna un nuevo objeto a 'a'. Esto se debe a que 'a' se desempaqueta automáticamente para realizar la multiplicación, y luego el resultado de la multiplicación se coloca automáticamente en la caja y se asigna a 'a'.
Entero es un objeto inmutable. (Todas las clases de envoltura son inmutables.)
Tomemos por ejemplo este pedazo de código:
static void test() {
Integer i = new Integer(10);
System.out.println("StartingMemory: " + System.identityHashCode(i));
changeInteger(i);
System.out.println("Step1: " + i);
changeInteger(++i);
System.out.println("Step2: " + i.intValue());
System.out.println("MiddleMemory: " + System.identityHashCode(i));
}
static void changeInteger(Integer i) {
System.out.println("ChangeStartMemory: " + System.identityHashCode(i));
System.out.println("ChangeStartValue: " + i);
i++;
System.out.println("ChangeEnd: " + i);
System.out.println("ChangeEndMemory: " + System.identityHashCode(i));
}
la salida será:
StartingMemory: 1373539035
ChangeStartMemory: 1373539035
ChangeStartValue: 10
ChangeEnd: 11
ChangeEndMemory: 190331520
Step1: 10
ChangeStartMemory: 190331520
ChangeStartValue: 11
ChangeEnd: 12
ChangeEndMemory: 1298706257
Step2: 11
MiddleMemory: 190331520
se puede ver la dirección de memoria para 'i' es cambiando (sus direcciones de memoria serán diferentes).
Ahora vamos a hacer una pequeña prueba con la reflexión, añade esta en el extremo del método test():
System.out.println("MiddleMemory: " + System.identityHashCode(i));
try {
final Field f = i.getClass().getDeclaredField("value");
f.setAccessible(true);
f.setInt(i, 15);
System.out.println("Step3: " + i.intValue());
System.out.println("EndingMemory: " + System.identityHashCode(i));
} catch (final Exception e) {
e.printStackTrace();
}
La salida adicional será:
MiddleMemory: 190331520
Step2: 15
MiddleMemory: 190331520
se puede ver que el la dirección de memoria para 'i' no cambió, aunque cambiamos su valor usando la reflexión.
(NO USE LA REFLEXIÓN DE ESTA MANERA EN LA VIDA REAL !!)
También le aconsejaría que verifique si el uso de Integer es REALMENTE necesario. Joshua señaló que usar primitivas es MUCHAS veces más rápido en Java efectivo. Entonces, si puedes, sigue con ** int **. –
Usar entero es en realidad una restricción de diseño. La idea es obtener un objeto entero y tengo que actualizar eso. Por lo tanto, no puedo deshacerme de eso :) – Jagmal