2010-09-11 11 views
9

Duplicar posibles:
What makes reference comparison (==) work for some strings in Java?El uso de '==' en lugar de .equals para las cadenas de Java

Sé que esto ha sido asked before, pero a pesar de las recomendaciones de uso en lugar de .equals() el operador de comparación ==, encontré que == funciona todo el tiempo:

String s1 = "Hello"; 
String s2 = "Hello"; 
System.out.println(s1 == s2); // true 

¿Alguien me puede dar un ejemplo del fallo del operador ==?

+0

Marcos proporcionó un [buen ejemplo] (http://stackoverflow.com/questions/767372/java-string-equals-versus/1251721#1251721) en una respuesta a la pregunta que enlazó. –

+0

Relacionados: http://stackoverflow.com/questions/9698260/what-makes-reference-comparison-work-for-some-strings-in-java/9698305#9698305 – berry120

Respuesta

37

Esto es porque tiene suerte. El operador == en Java comprueba la igualdad de referencia : devuelve verdadero si los punteros son los mismos. No verifica la igualdad de contenido. Las cadenas idénticas encontradas en tiempo de compilación se colapsan en una única instancia String, por lo que funciona con los literales String, pero no con las cadenas generadas en tiempo de ejecución.

Por ejemplo, "Foo" == "Foo" podría funcionar, pero "Foo" == new String("Foo") no, porque new String("Foo") crea una nueva instancia String, y rompe cualquier posible la igualdad puntero.

Más importante aún, másStrings que trata en un programa del mundo real son generados en tiempo de ejecución. La entrada del usuario en cuadros de texto es generada en tiempo de ejecución. Los mensajes recibidos a través de un socket son generados en tiempo de ejecución. Las cosas leídas de un archivo son generadas en tiempo de ejecución. Por lo tanto, es muy importante que use el método equals, y no el operador ==, si desea verificar la igualdad de contenido.

+3

Un poco de una nota adicional, la razón por la cual "foo" == "foo" realmente funciona, se debe a que todas las cadenas literales son internas http: // descargar .oracle.com/javase/1.4.2/docs/api/java/lang/String.html # intern() –

9

¿Alguien me puede dar un ejemplo de la falla del operador ==?

Ejemplo 1:

String s1 = new String("Hello"); 
String s2 = new String("Hello"); 
System.out.println(s1 == s2); // false 

Ejemplo 2:

Integer a=1000,b=1000; 
System.out.println(a == b); // false 
+1

Supongo que funcionará. ¿Pero no son las cadenas inmutables? Como tal, ¿no deberían ser internados? – Aillyn

+0

Se introducen cadenas literales. –

+1

"Hola" == "Hola" ==> verdadero. Sin embargo, la nueva Cadena ("Hola") asignará algo de memoria para un objeto, y lo mismo nuevamente asignará más memoria, en otro lugar, para otro objeto. Como el operador "==" compara referencias, devolverá falso. –

4

Al hacer esto, en realidad está creando literales de cadena:

String s1 = "Hello"; 
String s2 = "Hello"; 

El compilador encuentra literales de cadena idéntica y luego optimiza manteniendo un caso en el montón y hacer todas las variables en el punto de pila lo. Entonces, al hacer un == se devolverá verdadero porque apuntan a la misma dirección de memoria.

Al hacer esto, usted está creando cadena de objetos:

String s1 = new String("Hello"); 
String s2 = new String("Hello"); 

La instanciación creará espacio único en el montón para cada uno de éstos y las variables de pila apuntará a esos lugares separados. Por lo tanto, estos serán iguales usando .equals() porque sus valores son los mismos, pero no serán iguales usando == porque son objetos diferentes en el espacio de la memoria del montón.

4

Los desarrolladores de Java experimentados rara vez o nunca usan new String(String), pero el problema surge en otros casos también. Por ejemplo:

String hello = "Hello" 
String hell = hello.substring(0, 4); 
System.err.println("Hell" == hell); // should print "false". 

(La mayoría de los casos cadena en una aplicaciones del mundo real se forman ya sea tomando una subcadena de alguna otra cadena, o construyéndolo a partir de una serie de personajes muy pocas aplicaciones sólo se utilizarán instancias de String. creado como literales.)

+1

Una razón para usar "y = new String (x)" (donde x es una cadena) es para permitir recolección de basura, cuando x es una subcadena de una cadena muy grande. Si solo usa "y = x", la cadena muy grande no puede obtener basura recolectada siempre que se haga referencia a y. Si usa "new String (x)", se crea una nueva cadena que no hace referencia a la cadena grande original. –

+4

Eso es cierto, pero en mi experiencia rara vez es necesario. Y si no es necesario, entonces es en realidad una anti-optimización. –

Cuestiones relacionadas