Usar ‘==’ en lugar de .equals para cadenas de Java

Posible duplicado:
¿Qué hace que la comparación de referencia (==) funcione para algunas cadenas en Java?

Sé que esto se ha preguntado antes , pero a pesar de las recomendaciones para usar .equals() lugar del operador de comparación == , descubrí que == funciona todo el tiempo:

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

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

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

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

Más importante aún, la mayoría de las Strings que trabajas en un progtwig del mundo real están generadas 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.

¿Alguien puede darme 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 

Cuando haces esto, en realidad estás creando literales de cadena :

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

El comstackdor encuentra literales de cadena idénticos y luego los optimiza manteniendo una instancia en el montón y haciendo que todas las variables en la stack apunten a él. Así que hacer un == devolverá verdadero porque apuntan a la misma dirección de memoria.

Cuando haces esto, estás creando objetos de cadena :

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

La instanciación creará un espacio único en el montón para cada uno de estos y las variables de la stack apuntarán a esas ubicaciones separadas. 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.

Los desarrolladores de Java experimentados raramente o nunca usan un 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 las instancias String en aplicaciones del mundo real se forman tomando una subcadena de otra cadena o construyéndola a partir de una matriz de caracteres. Muy pocas aplicaciones solo usarán instancias String creadas como literales).