2012-01-19 9 views
5

Si String s son inmutables en Java, entonces ¿cómo podemos escribir como:Java cadenas inmutables confusión

String s = new String(); 
s = s + "abc"; 
+2

Porque 's' no es' final'. – SLaks

+1

s no es la cadena, es un contenedor que contiene una referencia a una cadena. Primero, contiene la referencia a la cadena devuelta por la nueva Cadena(), luego se cambia para mantener la referencia de la cadena que es devuelta por la nueva Cadena() + "abc", es decir, la referencia de otra cadena. – ignis

Respuesta

7

Su variable de cadena NO es la cadena. Es una REFERENCIA a una instancia de Cadena.

Vea usted mismo:

String str = "Test String"; 
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string 

str = str + "Another value"; 
System.out.println(System.identityHashCode(str)); // Whoa, it's a different string! 

las instancias la variable apunta a str son inmutables de forma individual, pero la variable puede ser dirigido a cualquier instancia de cadena que desea.

Si no quiere que sea posible reasignar str para que apunte a una instancia de cadena diferente, os lo último:

final String str = "Test String"; 
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string 

str = str + "Another value"; // BREAKS HORRIBLY 
+0

¿Cuál es el punto de convertir '' String's to 'Object's? – Natix

+0

Simple. str.toString() devuelve ... la cadena. Llamar ((Object) str) .toString() nos da la ID de instancia real. Esto es para demostraciones. –

+2

No, no es así. Los métodos en Java son virtuales, el lanzar un objeto a un súper tipo no tiene ningún efecto aquí. La implementación del método 'string '' overriden' toString() 'aún será llamada. Debes llamar a 'System.identityHashCode (str)' para obtener el hashCode basado en la identidad original de un objeto. – Natix

8

Cuerdas son inmutables.
Eso significa que una instancia de String no puede cambiar.

Estás cambiando la variable de s para referirse a un diferente (pero aún inmutable) String ejemplo.

0
String s = new String(); 

Crea una cadena nueva, inmutable, vacía, la variable "s" la hace referencia.

s = s+"abc";    

Crea una cadena nueva e inmutable; la concatenación de la cadena vacía y "abc", la variable "s" ahora hace referencia a este nuevo objeto.

1

clases inmutables son aquellos cuyos métodos pueden cambiar sus campos, por ejemplo:

Foo f = new Foo("a"); 
f.setField("b"); // Now, you are changing the field of class Foo 

pero en clases inmutables, por ejemplo, Cadena, no puede cambiar el objeto una vez que lo crea, pero por supuesto, puede reasignar la referencia a otro objeto. Por ejemplo:

String s = "Hello"; 
s.substring(0,1); // s is still "Hello" 
s = s.substring(0,1); // s is now referring to another object whose value is "H" 
0

Solo para aclarar, cuando dice s = s + "abc"; Eso significa que crea una nueva instancia de String (que se compone de s y "abc") y luego asigna esa nueva instancia de String a s. Entonces, la nueva referencia en s es diferente de la anterior.

Recuerde, una variable es efectivamente una referencia a un objeto en una ubicación de memoria específica. El objeto en esa ubicación permanece en esa ubicación, incluso si cambia la variable para hacer referencia a un nuevo objeto en una ubicación diferente.

2

La primera respuesta es absolutamente correcta. Debe marcarlo como respondido.

s = s+"abc" no se agrega al objeto s. crea una nueva cadena que contiene los caracteres del objeto s (del que no hay ninguno) y "abc".

si la cadena fue mutable. tendría métodos como append() y otros métodos mutantes similares que están en StringBuilder y StringBuffer.

Java efectivo por Josh Bloch tiene una excelente discusión sobre los objetos inmutables y su valor.

0
String s = new String(); 

se crea un objeto vacío String (""). Y la variable s se refiere a ese objeto.

s = s + "abc"; 

"abc" es una cadena literal para que pueda ser reutilizado (ya que las cadenas son inmutables y por lo tanto son constantes) (que no es sino un objeto String, que está implícita creado y mantenido en un charco de cadenas es). Pero cuando lo haces new String() es totalmente diferente porque estás creando explícitamente el objeto para que no termine en el grupo. Puedes lanzar está en el grupo por algo llamado internamiento.

Así, s + "abc" ya que en este punto y concatenación de cadena vacía ("") y "abc" en realidad no crear un nuevo objeto String porque el resultado final es "abc" que ya está en la piscina. Entonces, finalmente la variable s se referirá al literal "abc" en el grupo.

-2

Creo que todos están haciendo esto mucho más complicado de lo que necesita ser, ¡y eso simplemente confunde a las personas que intentan aprender!

El principal beneficio de hacer un objeto inmutable en Java es que puede ser pasado por referencia (por ejemplo, a otro método o asignado usando el operador de asignación) sin tener que preocuparse de aguas abajo cambia para el objeto que causa problemas en el método o contexto actual. (Esto es muy diferente a cualquier conversación sobre la seguridad de subprocesos de un objeto.)

Para ilustrar, cree una aplicación que pase una cadena como parámetro a un método diferente y modifique la cadena en ese método. Imprima la cadena al final del método llamado y luego, después del control, regrese al método de llamada. Las cadenas tendrán diferentes valores, y eso se debe a que apuntan a diferentes ubicaciones de memoria, un resultado directo de "cambiar" la cadena inmutable (creando un nuevo puntero y apuntándolo a un nuevo valor detrás de las escenas). Luego crea una aplicación que haga las mismas cosas excepto con StringBuffer, que no es inmutable. (Por ejemplo, puede agregar al StringBuffer para modificarlo). Los StringBuffers impresos tendrán los mismos valores, y esto se debe a que (a) se pasa por referencia, como hace Java con todos los objetos pasados ​​a los métodos como parámetros y (b) mutable

Espero que esto ayude a las personas que están leyendo este hilo y tratando de aprender!