2009-10-18 8 views

Respuesta

2

Para los tipos de referencia, == comparará la referencia real (donde reside el objeto en la memoria) donde el método igual realiza una comparación de los datos.

La JVM algunas veces "interpondrá en secuencia" sus cadenas inmutables por motivos de rendimiento. Causando esto:

String a = "abc"; 
String b = "abc"; 
if (a == b){ 
    //The if statement will evaluate to true, 
    //if your JVM string interns a and b, 
    //otherwise, it evaluates to false. 
} 

http://en.wikipedia.org/wiki/String_interning

+0

aprendieron un nuevo concepto - internar! – lft93ryt

1

El operador '==' trabaja en el tipo primitivo que tiene, que en el caso de los objetos de referencia es la propia referencia. Eso es a == b comparará los valores para tipos primitivos como int, pero comparará la referencia (no el valor) para los tipos de referencia. Dos objetos de tipo de referencia que no son iguales pero tienen el mismo valor devolverán true cuando se llame al método equals(), pero a == b será falso.

Para tipos primitivos, al llamar a un método, el tipo se convierte previamente (en recuadro) a un tipo de referencia y luego se llama al método. Esto significa que para los tipos primitivos a == b obtendrá el mismo valor que a.equals(b), pero en este último caso se crean dos objetos temporales en caja antes de llamar al método equals(). Esto hará que la operación sea más costosa en tiempo de CPU, lo que puede o no ser un problema dependiendo de dónde ocurra.

Es decir, para comparar los valores de tipo primitivo debe usar ==, mientras que para comparar los valores de tipo de referencia, debe usar el método .equals().

Lo mismo ocurre con el método toString(). Cuando se invoca a un objeto de tipo de referencia, llamará al método apropiado y producirá una Cadena. Cuando se invoca en un tipo primitivo, el tipo se autocapturará y luego se llamará al método en el objeto temporal. En este caso, puede llamar al método estático toString() apropiado (es decir, para la llamada internacional Integer.toString(myint)), esto evitará la creación del objeto temporal.

+0

'a.equals (b)' no se compilará si 'a' es de tipo primitivo. – ajb

7

Para los tipos regulares (incluyendo String):

  • == compara referencias a objetos. Prueba si dos referencias de objeto son iguales; es decir, si se refieren al mismo objeto.
  • equals(Object) prueba si este objeto es "igual a" otro. Qué significa "igual a" depende de cómo la clase del objeto define la igualdad. La clase java.lang.Object define equals(other) como this == other, pero muchas clases anulan esta definición.
  • toString() proporciona una conversión simple del objeto a una Cadena. El formato y contenido de la Cadena resultante es específico de la clase y (desde la perspectiva del contrato java.lang.Object) no hay garantías de que sea significativo.

Para (true) tipos primitivos:

  • == compara valores del tipo, y
  • equals() y toString() no están definidas. Java no le permite llamar a un método en un valor primitivo.

Sin embargo, esto se complica por el hecho de que en algunos contextos el lenguaje Java dice que un tipo primitivo puede ser "autoboxed" para dar una instancia de tipo correspondiente de la envoltura del tipo primitivo; p.ej. int corresponde a java.lang.Integer, y así sucesivamente. Para las clases de envoltura:

  • == se define el mismo que para cualquier otro tipo de referencia,
  • equals() compara los valores envueltos, y
  • toString() formatea los valores envueltos.

El palo en la rueda es ilustrado por el siguiente:

int a = ... 
int b = a; 
Integer aa = a;  // autoboxing occurs 
Integer bb = b;  // autoboxing occurs 

assert a == b;   // always succeeds 
assert aa.equals(bb); // always succeeds 
assert aa == bb;  // sometimes succeeds, sometimes fails. 

La razón de que el último a veces falla es que el JLS no garantiza que autoboxing un valor simple dado siempre dará el mismo envoltorio objeto. En algunos casos (por ejemplo, para enteros pequeños), y no para otros (por ejemplo, enteros grandes).

La lección que debe aprenderse del ejemplo anterior es que debe tener mucho cuidado con el uso de == en un tipo de referencia. Úselo únicamente cuando realmente desea probar si dos referencias son para el mismo objeto. No lo use si solo quiere probar si los objetos son "iguales" sin la sobrecarga de llamar al equals().

(También tenga en cuenta que es otro tipo String== donde se va a dar la respuesta equivocada en muchas situaciones; ver How do I compare strings in Java?.)

+0

'==' en primitivas solo verifica los valores e ignora los tipos. 'int x = 5; largo y = 5L; byte b = 5; x == y; b == x; 'Ambos devuelven verdadero. – arun

+1

No está "ignorando" los tipos. Uno u otro de los operandos se promociona al tipo del otro. Además, dije "valores del tipo" ... –

Cuestiones relacionadas