2012-03-22 15 views
11

El siguiente código me pareció realmente confuso ya que proporcionaba dos salidas diferentes. El código se probó en jdk 1.7.¿Cómo funcionan los operadores! = Y == en enteros en Java?

public class NotEq { 

public static void main(String[] args) { 

    ver1(); 
    System.out.println(); 
    ver2(); 
} 

public static void ver1() { 
    Integer a = 128; 
    Integer b = 128; 

    if (a == b) { 
     System.out.println("Equal Object"); 
    } 

    if (a != b) { 
     System.out.println("Different objects"); 
    } 

    if (a.equals(b)) { 
     System.out.println("Meaningfully equal."); 
    } 
} 

public static void ver2() { 
    Integer i1 = 127; 
    Integer i2 = 127; 
    if (i1 == i2) { 
     System.out.println("Equal Object"); 
    } 

    if (i1 != i2){ 
     System.out.println("Different objects"); 
    } 
    if (i1.equals(i2)){ 
     System.out.println("Meaningfully equal"); 
    } 
} 

} 

de salida:

[ver1 de salida]
Diferentes objetos
con significado igual.

[ver2 salida]
Equal Objeto
con significado igual

¿Por qué la == y! = Prueba produce resultados diferentes para ver1() y ver2() para mismo número mucho menor que el Integer. ¿VALOR MÁXIMO? ¿Se puede concluir que == verificar números mayores a 127 (para las clases contenedoras como Integer como se muestra en el código) es una pérdida de tiempo?

+3

Esto se debe a que el mecanismo de autoboxing almacena en caché y reutiliza el mismo objeto para valores en el rango -128 - 127. Este es un duplicado de una pregunta anterior. – aioobe

+0

@quixoto: ver mi respuesta de edición :) – BoltClock

+1

http://stackoverflow.com/questions/1700081/why-does-128-128-return-false-but-127-127-return-true-when-converting-to -integ –

Respuesta

10

Los enteros se almacenan en caché para valores entre -128 y 127, por lo que Integer i = 127 siempre devolverá la misma referencia. Integer j = 128 no necesariamente lo hará. Luego deberá usar equals para probar la igualdad del subyacente int.

Esto es parte de la Java Language Specification:

Si el valor p de ser en caja es verdadero, falso, un byte o un caracter en el rango \ u0000 a \ u007f, o un int o número corto entre -128 y 127 (inclusive), entonces, r1 y r2 sean los resultados de dos conversiones de boxeo cualquiera de p. Siempre es el caso que r1 == r2.

Pero 2 llamadas a Integer j = 128 podrían devolver la misma referencia (no garantizado):

Menos implementaciones de memoria limitada podría, por ejemplo, la caché todos los valores CHAR y cortas, así como int y largo valores en el rango de -32K a + 32K.

+0

El constructor no usa el almacenamiento en caché. Pruebe: System.out.println (new Integer (2) == new Integer (2)) – fgb

+1

'new Entero (127)' nunca devolverá la misma referencia. De hecho, garantiza crear siempre un nuevo objeto. Pero cuando se usa el auto-boxing como en 'Integer i = 127;' entonces se usa la caché. Por cierto, el borde superior 127 no es fijo sino un mínimo. Se puede configurar a un valor mayor pero no menor. –

4

Porque los enteros pequeños están internados en Java, y ha intentado los números en diferentes lados del límite de "pequeñez".

+0

@downvoter, ¿te gustaría detallar tu voto? – dasblinkenlight

0

Java almacena en caché los enteros de -128 a 127 Es por eso que los objetos son los mismos.

0

Creo que los operadores == y! = Al tratar con primitivas funcionarán de la forma en que los está usando actualmente, pero con objetos (Integer vs. int) querrá realizar pruebas con el método .equals().

No estoy seguro de esto, pero con los objetos, el == probará si un objeto es el mismo objeto o no, mientras que .equals() realizará la prueba de que esos dos objetos contienen equivalencia en el valor (o el método deberá crearse/anularse) para objetos personalizados.

3

Existe un caché de objetos Integer desde -128 y hasta 127 por defecto. El borde superior se puede configurar.La frontera caché superior puede ser controlado por la opción VM -XX:AutoBoxCacheMax=<size>

está usando este caché cuando se utiliza la forma:

Integer i1 = 127; 

o

Integer i1 = Integer.valueOf(127); 

Pero cuando se utiliza

Integer i1 = new Integer(127); 

, entonces tiene la garantía de obtener un nuevo objeto que no esté en la memoria caché. En este último caso, ambas versiones imprimen los mismos resultados. Usando las versiones en caché pueden diferir.

+0

Es bueno saberlo. Por favor, no hagas eso en producción. – atamanroman

Cuestiones relacionadas