2010-03-23 34 views
10
Integer i = 127; 
Integer j = 127; 
System.out.println(i == j); 
System.out.println(i.equals(j)); 

Integer i1 = 128; 
Integer j1 = 128; 
System.out.println(i1 == j1); 
System.out.println(i1.equals(j1)); 

No entiendo por qué su impresión no es "verdadera, verdadera, verdadera, verdadera". por favor da respuesta?El siguiente código imprime "verdadero, verdadero, falso, verdadero". ¿No debería ser "verdadero, verdadero, verdadero"?

+2

una pregunta tan específica, hmm, sospechoso – Will

+1

@Will He visto la misma pregunta en un libro SCJP –

+1

apuesto a que devuelve falso, verdadero, falso, verdadero en lugar de verdadero, verdadero, falso, verdadero –

Respuesta

29

Cuando usa ==, está comparando las instancias de objeto para la igualdad.

La razón de que los dos primeros casos son iguales, es que se ha creado el Integers utilizando autoboxing (en lugar de llamar new Integer(127)), y la Java Language Specification §5.1.7 requiere que Integers entre -128 y 127 se almacenan en caché.

Implementaciones caché caché más valores que eso, pero no están obligados a hacerlo; al parecer, la JVM que está utilizando no almacena en caché 128. Este es el caso de Sun Java 6.

5

Entero es una clase. Si escribe nuevo Integer(), crea un nuevo objeto. Entonces, i, j, i1 y j1 son todos objetos diferentes. Si usa ==, solo es verdadero en el mismo objeto. Para enteros menores a 128, la JVM usa siempre el mismo objeto, por lo que las salidas son verdaderas.

4

No, no debe:

Integer i1 = 128; 
Integer j1 = 128; 

Autoboxing hace que dos objetos Integer distintas a crearse en la implementación de Java que está utilizando.

Si los valores enteros estaban en el rango de -128 a 127, el JLS indica que se usaría el mismo objeto entero; ver JLS 1.5.7. Sin embargo, el JLS hace no requiere que i1 y i2 deben tener valores diferentes fuera de ese rango. De hecho, la siguiente discusión en el JLS dice esto:

Idealmente, encajonar un valor primitivo dado p, siempre arrojaría una referencia idéntica. En la práctica, esto puede no ser factible utilizando las técnicas de implementación existentes. Las reglas anteriores son un compromiso pragmático. La cláusula final anterior requiere que ciertos valores comunes siempre estén enmarcados en objetos indistinguibles. La implementación puede almacenarlos en caché, de forma perezosa o ansiosa.

Para otros valores, esta formulación no permite suposiciones sobre la identidad de los valores encuadrados por el programador. Esto permitiría (pero no requeriría) compartir algunas o todas estas referencias.

Esto asegura que en la mayoría de los casos comunes, el comportamiento será el deseado, sin imponer una penalización de rendimiento excesiva, especialmente en dispositivos pequeños. Las implementaciones menos limitadas de memoria podrían, por ejemplo, almacenar en caché todos los caracteres y cortos, así como enteros y largos en el rango de -32K - + 32K.

+0

¿Cómo deletreas 2 en inglés? –

+0

@PP - debe ser después de su hora de acostarse :-) –

+0

Si mal no recuerdo, Sun Java 7 va a tener un caché Integer configurable. Creo que es particularmente útil en algunos puntos de referencia. –

9

sólo para añadir a todas las otras respuestas correctas, echar un vistazo a la source code con el fin de entender completamente lo que está diciendo @mmyers:

584  /** 
    585  * Returns an {@code Integer} instance representing the specified 
    586  * {@code int} value. If a new {@code Integer} instance is not 
    587  * required, this method should generally be used in preference to 
    588  * the constructor {@link #Integer(int)}, as this method is likely 
    589  * to yield significantly better space and time performance by 
    590  * caching frequently requested values. 
    591  * 
    592  * @param i an {@code int} value. 
    593  * @return an {@code Integer} instance representing {@code i}. 
    594  * @since 1.5 
    595  */ 
    596  public static Integer valueOf(int i) { 
    597   final int offset = 128; 
    598   if (i >= -128 && i <= 127) { // must cache 
    599    return IntegerCache.cache[i + offset]; 
    600   } 
    601   return new Integer(i); 
    602  } 
+2

También debe saber que 'Integer i = x' se compila en' Integer.valueOf (x) 'internamente, que es. –

+0

Gracias, sentí que faltaba algo. – Tom

Cuestiones relacionadas