2009-02-27 12 views
7
String s1 = "BloodParrot is the man"; 
String s2 = "BloodParrot is the man"; 
String s3 = new String("BloodParrot is the man"); 

System.out.println(s1.equals(s2)); 
System.out.println(s1 == s2); 
System.out.println(s1 == s3); 
System.out.println(s1.equals(s3)); 

// salida
cierto
cierto
falsa
ciertola igualdad frente a la igualdad de ubicación

¿Por qué no todas las cadenas tienen la misma ubicación en la memoria si los tres tienen la misma ¿contenido?

+0

Es este Java o C#. La respuesta a su pregunta parece depender del idioma. Es posible que desee etiquetarlo en consecuencia. –

+0

Esto no es un duplicado. Esta pregunta es más acerca de las cadenas de internados de lo que se trata de compararlos. –

+0

Supongo que el último comentario no tiene sentido a menos que mencione que revertí una edición diciendo que esta pregunta era un duplicado de otra. Siéntase libre de agregar el enlace nuevamente y votar para cerrar si no está de acuerdo. –

Respuesta

15

Java solo interna automáticamente String literales. Los nuevos objetos String (creados con la palabra clave new) no se internan por defecto. Puede usar el método String.intern() para internar un objeto String existente. Llamar al intern comprobará el conjunto de cadenas existente para un objeto coincidente y lo devolverá si existe o lo agregará si no hubiera coincidencia.

Si se agrega la línea

s3 = s3.intern(); 

a su código justo después de crear s3, verá la diferencia en su salida.

See some more examples and a more detailed explanation.

Esto, por supuesto, trae a colación el tema muy importante de cuándo usar == y cuándo usar el método equals en Java. Casi siempre desea utilizar equals al tratar con referencias de objeto. El operador == compara los valores de referencia, que es casi, nunca lo que quiere comparar. Conocer la diferencia lo ayuda a decidir cuándo es apropiado usar == o equals.

3

Llama explícitamente a new para s3 y esto le deja con una nueva instancia de la cadena.

+0

Ah, entonces la única diferencia es el uso de la palabra clave "nueva". Entonces, ¿las cadenas que no usan la nueva palabra clave no son instancias de un objeto de cadena? – BloodParrot

+0

Son instancias, pero es posible que no necesariamente tengan búferes dedicados. – sharptooth

1

¿Por qué no todas las cadenas tienen la misma ubicación en la memoria si las tres tienen el mismo contenido?

Porque son diferentes cadenas con el mismo contenido!

+0

Cadena s1 = "BloodParrot es el hombre"; Cadena s2 = "BloodParrot es el hombre"; s1 == s2 => true Parece que s1 y s2 son las MISMAS cadenas. –

+0

Sí. Lo siento. ¡Estaba equivocado! :( – Bharani

+0

Esos dos * son * idénticos, apuntando a la misma dirección. Solo s3 es diferente, porque se crea explícitamente como una nueva cadena – erickson

2

Crear un String es en realidad un proceso rápido. Tratar de encontrar cualquier String previamente creado será mucho más lento.

Considera lo que tienes que hacer para hacer que todos String s sean internados. Debe buscar un conjunto de todos los String s previamente construidos. Tenga en cuenta que esto debe hacerse de una manera segura para subprocesos, lo que agrega sobrecarga. Como no desea que se filtre, debe utilizar alguna forma de referencias no sólidas (sin hilos).

Por supuesto, no puede implementar Java de esta manera porque la biblioteca desafortunadamente expone constructores para String sy la mayoría de los demás objetos de valor inmutables.

1

Hay un método llamado String.intern que, esencialmente, toma todas las cadenas que son iguales y las pone en una tabla hash (estoy mintiendo, pero para esto es el concepto lo que importa, no la realidad)

String s1 = "BloodParrot is the man"; 
String s2 = "BloodParrot is the man"; 
String s3 = new String("BloodParrot is the man").intern(); 

System.out.println(s1.equals(s2)); 
System.out.println(s1 == s2); 
System.out.println(s1 == s3); 
System.out.println(s1.equals(s3)); 

debe tenerlos todos siendo "verdaderos". Esto se debe a que (y estoy mintiendo un poco más aquí, pero solo importa para el concepto, no para la realidad). Cadena s1 = "BloodParrot es el hombre"; se hace algo así como String s1 = "BloodParrot es el hombre" .intern();