2010-01-07 13 views
15

Así que me hicieron esta pregunta hoy.Primitivas en caja y equivalencia

Integer a = 3; 
Integer b = 2; 
Integer c = 5; 
Integer d = a + b; 
System.out.println(c == d); 

¿Qué imprime este programa? Devuelve verdadero. Respondí que siempre se imprimirá en falso debido a la forma en que entendí el boxeo automático (y automático). Tenía la impresión de que al asignar Integer a = 3 se creará un nuevo Integer (3) para que an == evalúe la referencia en lugar del valor primitivo.

¿Alguien puede explicar esto?

+0

http://meta.stackexchange.com/questions/147643/should-i-vote-to-close-a-duplicate-question-even-though-though-muchy-newer-and-ha –

+0

Pero posible duplicado de http : //stackoverflow.com/questions/1700081/why-does-128-128-return-false-but-127-127-return-true-when-converting-to-integ es más apropiado, el anterior era incorrecto. Pero tal vez ambos están equivocados ;-) –

Respuesta

20

Los valores en caja entre -128 y 127 están en caché. El boxeo usa el método Integer.valueOf, que usa la caché. Los valores fuera del rango no se almacenan en la memoria caché y siempre se crean como una nueva instancia. Dado que sus valores caen en el rango de caché, los valores son iguales usando == operator.

Presupuesto de especificación del lenguaje Java:

Si el valor p de ser encajonado es cierto, falsa, un byte, un char en el rango \ u0000 a \ u007f, o un int o corto número entre -128 y 127, luego deje que r1 y r2 sean los resultados de cualesquiera dos conversiones de boxeo de p. Siempre es el caso que r1 == r2.

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

+0

+1: ustedes saben tanto :) ¿Pueden proporcionar un enlace a alguna documentación en la que podamos aprender más acerca de este caché? – gameover

+1

Ver la fuente del JDK. Vaya a src.zip/java/lang/Integer.java y busca "caché = nuevo entero [256];". Esa es la inicialización. A continuación, busque "Entero público static valueOf (int i)". Ese es un método que usa la caché para devolver el instante en caché cada vez que se solicita uno de esos valores. – helios

+0

java.lang.Character también tiene un caché para caracteres entre unicodes 0 y 127 (ascii-7/us-ascii). – helios

11

Esto es lo que realmente está sucediendo:

Integer c = Integer.valueOf(5); 
Integer d = Integer.valueOf(a.intValue() + b.intValue()); 

Java mantiene una caché de objetos Integer entre -128 y 127. Comparar con lo siguiente:

Integer a = 300; 
Integer b = 200; 
Integer c = 500; 
Integer d = a + b; 
System.out.println(c == d); 

que debería imprimir false.

5

Es porque algunos de los Enteros (en caja automática) están en caché, por lo que en realidad está comparando la misma referencia: this post tiene ejemplos más detallados y una explicación.

4

almacenamiento en caché que sucede fuera de autoboxing también, considere esto:

Integer a = 1; 
Integer b = new Integer(1); 
Integer c = Integer.valueOf(1); 

System.out.println(a == b); 
System.out.println(b == c); 
System.out.println(c == a); 

Esto imprimirá:

false 
false 
true 

Así que supongo que por lo general desea mantenerse alejado de '==' cuando se comparan los objetos

+0

Tienes razón. Esto es resultado de que el almacenamiento en caché se implementa en el método 'valueOf'. –

+0

Sí, pero curiosamente no está en Integer.valueOf (String s). Que desastre. –