2010-11-07 19 views
18

Se supone que las clases de envoltura de Java son inmutables. Esto significa que una vez que se crea un objeto, por ejemplo,¿Las clases de envoltura de Java son realmente inmutables?

Integer i = new Integer(5); 

su valor no se puede cambiar. Sin embargo, haciendo

i = 6; 

es perfectamente válido.

Entonces, ¿qué significa la inmutabilidad en este contexto? ¿Tiene esto que ver con el auto-boxing/unboxing? Si es así, ¿hay alguna forma de evitar que el compilador lo haga?

Gracias

Respuesta

25

i es una referencia. Su código cambia la referencia i para apuntar a un Integer diferente, igualmente inmutable.

final Integer i = Integer.valueOf(5); 

puede ser más útil.

18

Inmutable significa que el estado del objeto no se puede cambiar. En su caso, no ha cambiado el objeto new Integer(5), pero ha cambiado la referencia i para que apunte a otro objeto. Espero que esté claro :)

5

El motivo i = 6 funciona es que el auto-boxeo está interceptando y convirtiéndolo en i = new Integer(6). Por lo tanto, como dijo @Peter, ahora estás apuntando a un nuevo objeto.

+0

Casi - efectivamente lo convierte en 'Integer.valueOf (6)'. Consulte esto para obtener más información: http://marxsoftware.blogspot.com/2010/08/subtle-nuance-of-new-keyword-with.html –

+0

Vaya. My Bad :-) No me había molestado en buscar exactamente a qué se traducía. – drekka

11

El compilador autoboxes valores primitivos, esto significa que

Integer value = 6; 

se compilará como

Integer value = Integer.valueOf(6); 

Integer.valueOf devolverá un ejemplo entero con el valor dado. En su caso, i ahora hará referencia al entero (6) en lugar del entero (5), el entero (5) objeto no cambiará.

Para ver esto, puede hace el siguiente

Integer i = new Integer(5);//assign new integer to i 
Integer b = i;//b refences same integer as i 
i = 6;//modify i 
System.out.println(i +"!="+b); 

Esto imprimirá 6!=5, si la instancia número entero había sido modificado sería imprimir 6!=6 lugar.

Para aclarar esto, solo se pretende mostrar cómo una asignación a Entero solo modifica la referencia y no altera la instancia de Entero. Como el usuario @KNU señala que no prueba ni muestra la inmutabilidad de Integer, hasta donde puedo decir, la inmutabilidad solo está indirectamente dada por la falta de métodos de modificación en su API y el requisito de que las instancias devueltas por Integer.valueOf tengan que estar en caché para un cierto rango

+0

Esta es una entrada de blog bastante interesante sobre la igualdad primitiva/objeto: http://marxsoftware.blogspot.com/2010/08/subtle-nuance-of-new-keyword-with.html –

+0

este ejemplo no prueba la inmutabilidad de 'Entero 'de cualquier manera. ".... si la instancia entera hubiera sido modificada, imprimiría 6! = 6 en su lugar". OK, ¿qué hay de repetir la prueba anterior en el objeto mutable saber 'AtomicInteger' ??? aún imprimiría '6! = 5', arrojando agua sobre el argumento anterior. – KNU

+0

Nota: para la prueba sugerida anteriormente se debe usar 'i = new AtomicInteger (6);' en lugar de 'i = 6;' – KNU

Cuestiones relacionadas